def test_parse_csr(self): with open(os.path.join(fixtures_dir, 'test-inter-der.csr'), 'rb') as f: certification_request = csr.CertificationRequest.load(f.read()) cri = certification_request['certification_request_info'] self.assertEqual('v1', cri['version'].native) self.assertEqual( util.OrderedDict([ ('country_name', 'US'), ('state_or_province_name', 'Massachusetts'), ('locality_name', 'Newbury'), ('organization_name', 'Codex Non Sufficit LC'), ('organizational_unit_name', 'Testing Intermediate'), ('common_name', 'Will Bond'), ('email_address', '*****@*****.**'), ]), cri['subject'].native) self.assertEqual( util.OrderedDict([ ('algorithm', 'rsa'), ('parameters', None), ]), cri['subject_pk_info']['algorithm'].native) self.assertEqual( 24141757533938720807477509823483015516687050697622322097001928034085434547050399731881871694642845241206788286795830006142635608141713689209738431462004600429798152826994774062467402648660593454536565119527837471261495586474194846971065722669734666949739228862107500673350843489920495869942508240779131331715037662761414997889327943217889802893638175792326783316531272170879284118280173511200768884738639370318760377047837471530387161553030663446359575963736475504659902898072137674205021477968813148345198711103071746476009234601299344030395455052526948041544669303473529511160643491569274897838845918784633403435929, # noqa cri['subject_pk_info']['public_key'].parsed['modulus'].native) self.assertEqual( 65537, cri['subject_pk_info'] ['public_key'].parsed['public_exponent'].native) self.assertEqual([], cri['attributes'].native)
def test_curve_info_specified(self): with open(os.path.join(fixtures_dir, 'keys/test-pkcs8-ec-der.key'), 'rb') as f: private_key = keys.PrivateKeyInfo.load(f.read()) curve = ( 'specified', util.OrderedDict([ ('version', 'ecdpVer1'), ( 'field_id', util.OrderedDict([ ('field_type', 'prime_field'), ('parameters', 115792089210356248762697446949407573530086143415290314195533631308867097853951) ]) ), ( 'curve', util.OrderedDict([ ( 'a', b'\xFF\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC' ), ( 'b', b'\x5A\xC6\x35\xD8\xAA\x3A\x93\xE7\xB3\xEB\xBD\x55\x76\x98\x86\xBC' b'\x65\x1D\x06\xB0\xCC\x53\xB0\xF6\x3B\xCE\x3C\x3E\x27\xD2\x60\x4B' ), ( 'seed', b'\xC4\x9D\x36\x08\x86\xE7\x04\x93\x6A\x66\x78\xE1\x13\x9D\x26\xB7\x81\x9F\x7E\x90' ), ]) ), ( 'base', b'\x04\x6B\x17\xD1\xF2\xE1\x2C\x42\x47\xF8\xBC\xE6\xE5\x63\xA4\x40\xF2\x77\x03\x7D' b'\x81\x2D\xEB\x33\xA0\xF4\xA1\x39\x45\xD8\x98\xC2\x96\x4F\xE3\x42\xE2\xFE\x1A\x7F' b'\x9B\x8E\xE7\xEB\x4A\x7C\x0F\x9E\x16\x2B\xCE\x33\x57\x6B\x31\x5E\xCE\xCB\xB6\x40' b'\x68\x37\xBF\x51\xF5' ), ( 'order', 115792089210356248762697446949407573529996955224135760342422259061068512044369 ), ('cofactor', 1), ('hash', None), ]) ) self.assertEqual(curve, private_key.curve) with open(os.path.join(fixtures_dir, 'keys/test-public-ec-der.key'), 'rb') as f: public_key = keys.PublicKeyInfo.load(f.read()) self.assertEqual(curve, public_key.curve)
def test_parse_ec_private_key(self): with open(os.path.join(fixtures_dir, 'keys/test-ec-der.key'), 'rb') as f: key = keys.ECPrivateKey.load(f.read()) self.assertEqual('ecPrivkeyVer1', key['version'].native) self.assertEqual( 105342176757643535635985202437872662036661123763048203788770333621775587689309, key['private_key'].native) self.assertEqual( util.OrderedDict([ ('version', 'ecdpVer1'), ('field_id', util.OrderedDict([ ('field_type', 'prime_field'), ('parameters', 115792089210356248762697446949407573530086143415290314195533631308867097853951 ) ])), ('curve', util.OrderedDict([ ('a', b'\xFF\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC' ), ('b', b'\x5A\xC6\x35\xD8\xAA\x3A\x93\xE7\xB3\xEB\xBD\x55\x76\x98\x86\xBC' b'\x65\x1D\x06\xB0\xCC\x53\xB0\xF6\x3B\xCE\x3C\x3E\x27\xD2\x60\x4B' ), ('seed', b'\xC4\x9D\x36\x08\x86\xE7\x04\x93\x6A\x66\x78\xE1\x13\x9D\x26\xB7\x81\x9F\x7E\x90' ), ])), ('base', b'\x04\x6B\x17\xD1\xF2\xE1\x2C\x42\x47\xF8\xBC\xE6\xE5\x63\xA4\x40\xF2\x77' b'\x03\x7D\x81\x2D\xEB\x33\xA0\xF4\xA1\x39\x45\xD8\x98\xC2\x96\x4F\xE3\x42' b'\xE2\xFE\x1A\x7F\x9B\x8E\xE7\xEB\x4A\x7C\x0F\x9E\x16\x2B\xCE\x33\x57\x6B' b'\x31\x5E\xCE\xCB\xB6\x40\x68\x37\xBF\x51\xF5'), ('order', 115792089210356248762697446949407573529996955224135760342422259061068512044369 ), ('cofactor', 1), ('hash', None), ]), key['parameters'].native) self.assertEqual( b'\x04\x8B\x5D\x4C\x71\xF7\xD6\xC6\xA3\x49\x63\x42\x5C\x47\x9F\xCB\x73\x24\x1D\xC9\xDD' b'\xD1\x2D\xF1\x3A\x9F\xB7\x04\xDE\x20\xD0\x58\x00\x93\x54\xF6\x89\xC7\x2F\x87\x2B\xF7' b'\xF9\x3D\x3B\x34\xED\x9E\x7B\x0E\x3D\x57\x42\xDF\x78\x03\x0B\xCC\x31\xC6\x03\xD7\x9F' b'\x60\x01', key['public_key'].native)
def test_parse_csr2(self): with open(os.path.join(fixtures_dir, 'test-third-der.csr'), 'rb') as f: certification_request = csr.CertificationRequest.load(f.read()) cri = certification_request['certification_request_info'] self.assertEqual('v1', cri['version'].native) self.assertEqual( util.OrderedDict([ ('country_name', 'US'), ('state_or_province_name', 'Massachusetts'), ('locality_name', 'Newbury'), ('organization_name', 'Codex Non Sufficit LC'), ('organizational_unit_name', 'Test Third-Level Certificate'), ('common_name', 'Will Bond'), ('email_address', '*****@*****.**'), ]), cri['subject'].native) self.assertEqual( util.OrderedDict([ ('algorithm', 'rsa'), ('parameters', None), ]), cri['subject_pk_info']['algorithm'].native) self.assertEqual( 24242772097421005542208203320016703216069397492249392798445262959177221203301502279838173203064357049006693856302147277901773700963054800321566171864477088538775137040886151390015408166478059887940234405152693144166884492162723776487601158833605063151869850475289834250129252480954724818505034734280077580919995584375189497366089269712298471489896645221362055822887892887126082288043106492130176555423739906252380437817155678204772878611148787130925042126257401487070141904017757131876614711613405231164930930771261221451019736883391322299033324412671768599041417705072563016759224152503535867541947310239343903761461, # noqa cri['subject_pk_info']['public_key'].parsed['modulus'].native) self.assertEqual( 65537, cri['subject_pk_info'] ['public_key'].parsed['public_exponent'].native) self.assertEqual([ util.OrderedDict([ ('type', 'extension_request'), ('values', [[ util.OrderedDict([ ('extn_id', 'basic_constraints'), ('critical', False), ('extn_value', util.OrderedDict([ ('ca', False), ('path_len_constraint', None), ])), ]), util.OrderedDict([ ('extn_id', 'key_usage'), ('critical', False), ( 'extn_value', set([ 'digital_signature', 'non_repudiation', 'key_encipherment' ]), ), ]) ]]), ]), ], cri['attributes'].native)
def test_bad_teletex_inside_pkcs7(self): with open( os.path.join(fixtures_dir, 'mozilla-generated-by-openssl.pkcs7.der'), 'rb') as f: content = cms.ContentInfo.load(f.read())['content'] self.assertEqual( util.OrderedDict([('organizational_unit_name', 'Testing'), ('country_name', 'US'), ('locality_name', 'Mountain View'), ('organization_name', 'Addons Testing'), ('state_or_province_name', 'CA'), ('common_name', '{02b860db-e71f-48d2-a5a0-82072a93d33c}')]), content['certificates'][0].chosen['tbs_certificate'] ['subject'].native)
def unarmor_armor_files(): return ( ('keys/test.crt', 'keys/test-der.crt', 'CERTIFICATE', {}), ('keys/test-inter.crt', 'keys/test-inter-der.crt', 'CERTIFICATE', {}), ('keys/test-third.crt', 'keys/test-third-der.crt', 'CERTIFICATE', {}), ('keys/test-pkcs8.key', 'keys/test-pkcs8-der.key', 'PRIVATE KEY', {}), ('test-third.csr', 'test-third-der.csr', 'CERTIFICATE REQUEST', {}), ('keys/test-aes128.key', 'keys/test-aes128-der.key', 'RSA PRIVATE KEY', util.OrderedDict([ ('Proc-Type', '4,ENCRYPTED'), ('DEK-Info', 'AES-128-CBC,01F6EE04516C912788B11BD7377626C2') ])), )
def test_explicit_application_tag_nested(self): # tag = [APPLICATION 10] constructed; length = 18 # OUTER SEQUENCE: tag = [UNIVERSAL 16] constructed; length = 16 # outernumber : tag = [11] constructed; length = 3 # INTEGER: tag = [UNIVERSAL 2] primitive; length = 1 # 23 # inner : tag = [12] constructed; length = 9 # tag = [APPLICATION 20] constructed; length = 7 # INNER SEQUENCE: tag = [UNIVERSAL 16] constructed; length = 5 # innernumber : tag = [21] constructed; length = 3 # INTEGER: tag = [UNIVERSAL 2] primitive; length = 1 # 42 der = (b'\x6A\x12\x30\x10\xAB\x03\x02\x01\x17\xAC\x09\x74' b'\x07\x30\x05\xB5\x03\x02\x01\x2A') ato = ApplicationTaggedOuter.load(der) self.assertEqual(((1, 10), ), ato.explicit) self.assertEqual(0, ato.class_) self.assertEqual(16, ato.tag) self.assertEqual(1, ato.method) onum = ato['outernumber'] self.assertEqual(((2, 11), ), onum.explicit) self.assertEqual(0, onum.class_) self.assertEqual(2, onum.tag) self.assertEqual(0, onum.method) self.assertEqual(23, onum.native) ati = ato['inner'] self.assertEqual(((1, 20), (2, 12)), ati.explicit) self.assertEqual(0, ati.class_) self.assertEqual(16, ati.tag) self.assertEqual(util.OrderedDict([('innernumber', 42)]), ati.native) inum = ati['innernumber'] self.assertEqual(((2, 21), ), inum.explicit) self.assertEqual(0, inum.class_) self.assertEqual(2, inum.tag) self.assertEqual(0, inum.method) self.assertEqual(42, inum.native) self.assertEqual(der, ato.dump(force=True))
def test_explicit_field_default(self): val = ExplicitFieldDefault.load( b'\x30\x0f\x03\x02\x06@\xa2\x090\x07\x06\x02*\x03\x02\x01\x01') self.assertEqual(set(['one']), val['bits'].native) self.assertEqual(util.OrderedDict([('id', '1.2.3'), ('value', 1)]), val['seq'].native)
def test_parse_content_info_pkcs7_signed_digested_data(self): with open(os.path.join(fixtures_dir, 'pkcs7-signed-digested.der'), 'rb') as f: info = cms.ContentInfo.load(f.read()) signed_data = info['content'] encap_content_info = signed_data['encap_content_info'] self.assertEqual('signed_data', info['content_type'].native) self.assertEqual('v1', signed_data['version'].native) self.assertEqual([ util.OrderedDict([ ('algorithm', 'sha256'), ('parameters', None), ]) ], signed_data['digest_algorithms'].native) self.assertEqual('digested_data', encap_content_info['content_type'].native) self.assertEqual( util.OrderedDict([ ('version', 'v0'), ('digest_algorithm', util.OrderedDict([ ('algorithm', 'sha1'), ('parameters', None), ])), ('encap_content_info', util.OrderedDict([ ('content_type', 'data'), ('content', b'This is the message to encapsulate in PKCS#7/CMS\n'), ])), ('digest', b'\x53\xC9\xDB\xC1\x6D\xDB\x34\x3B\x28\x4E\xEF\xA6\x03\x0E\x02\x64\x79\x31\xAF\xFB' ) ]), encap_content_info['content'].native) self.assertEqual(1, len(signed_data['certificates'])) certificate = signed_data['certificates'][0] with open(os.path.join(fixtures_dir, 'keys/test-der.crt'), 'rb') as f: self.assertEqual(f.read(), certificate.dump()) self.assertEqual(1, len(signed_data['signer_infos'])) signer = signed_data['signer_infos'][0] self.assertEqual('v1', signer['version'].native) self.assertEqual( util.OrderedDict([ ('issuer', util.OrderedDict([ ('country_name', 'US'), ('state_or_province_name', 'Massachusetts'), ('locality_name', 'Newbury'), ('organization_name', 'Codex Non Sufficit LC'), ('organizational_unit_name', 'Testing'), ('common_name', 'Will Bond'), ('email_address', '*****@*****.**'), ])), ('serial_number', 13683582341504654466) ]), signer['sid'].native) self.assertEqual( util.OrderedDict([ ('algorithm', 'sha256'), ('parameters', None), ]), signer['digest_algorithm'].native) signed_attrs = signer['signed_attrs'] self.assertEqual(0, len(signed_attrs)) self.assertEqual( util.OrderedDict([ ('algorithm', 'rsassa_pkcs1v15'), ('parameters', None), ]), signer['signature_algorithm'].native) self.assertEqual( b'\x70\xBC\x18\x82\x41\xD6\xD8\xE7\x5C\xDC\x42\x27\xA5\xA8\xAA\x8B\x16\x15\x61\x3A\xE5\x47' b'\x53\xFD\x8F\x45\xA3\x82\xE2\x72\x44\x07\xD1\xCB\xBF\xB4\x85\x4A\x2A\x16\x19\xDE\xDC\x53' b'\x15\xCF\x98\xEE\x5C\x0E\xDF\xDE\xC8\x79\xCE\x2B\x38\x61\x36\xB0\xA1\xCB\x94\xD6\x4F\xCD' b'\x83\xEF\x0C\xC9\x23\xA0\x7B\x8B\x65\x40\x5C\x3D\xA8\x3E\xCC\x0D\x1F\x17\x23\xF3\x74\x9F' b'\x7E\x88\xF8\xF3\xBE\x4E\x19\x95\x0F\xEB\x95\x55\x69\xB4\xAA\xC3\x2A\x36\x03\x93\x1C\xDC' b'\xE5\x65\x3F\x4E\x5E\x03\xC8\x56\xD8\x57\x8F\xE8\x2D\x85\x32\xDA\xFD\x79\xD4\xDD\x88\xCA' b'\xA3\x14\x41\xE4\x3B\x03\x88\x0E\x2B\x76\xDC\x44\x3D\x4D\xFF\xB2\xC8\xC3\x83\xB1\x33\x37' b'\x53\x51\x33\x4B\xCA\x1A\xAD\x7E\x6A\xBC\x61\x8B\x84\xDB\x7F\xCF\x61\xB2\x1D\x21\x83\xCF' b'\xB8\x3F\xC6\x98\xED\xD8\x66\x06\xCF\x03\x30\x96\x9D\xB4\x7A\x16\xDF\x6E\xA7\x30\xEB\x77' b'\xF7\x40\x13\xFB\xF2\xAC\x41\x79\x9D\xDC\xC0\xED\x4B\x8B\x19\xEE\x05\x3D\x61\x20\x39\x7E' b'\x80\x1D\x3A\x23\x69\x48\x43\x60\x8B\x3E\x63\xAD\x01\x7A\xDE\x6F\x01\xBA\x51\xF3\x4B\x14' b'\xBF\x6B\x77\x1A\x32\xC2\x0C\x93\xCC\x35\xBC\x66\xC6\x69', signer['signature'].native)
def test_parse_content_info_pkcs7_signed_data(self): with open(os.path.join(fixtures_dir, 'pkcs7-signed.der'), 'rb') as f: info = cms.ContentInfo.load(f.read()) signed_data = info['content'] encap_content_info = signed_data['encap_content_info'] self.assertEqual('signed_data', info['content_type'].native) self.assertEqual('v1', signed_data['version'].native) self.assertEqual([ util.OrderedDict([ ('algorithm', 'sha256'), ('parameters', None), ]) ], signed_data['digest_algorithms'].native) self.assertEqual('data', encap_content_info['content_type'].native) self.assertEqual(b'This is the message to encapsulate in PKCS#7/CMS\n', encap_content_info['content'].native) self.assertEqual(1, len(signed_data['certificates'])) certificate = signed_data['certificates'][0] with open(os.path.join(fixtures_dir, 'keys/test-der.crt'), 'rb') as f: self.assertEqual(f.read(), certificate.dump()) self.assertEqual(1, len(signed_data['signer_infos'])) signer = signed_data['signer_infos'][0] self.assertEqual('v1', signer['version'].native) self.assertEqual( util.OrderedDict([ ('issuer', util.OrderedDict([ ('country_name', 'US'), ('state_or_province_name', 'Massachusetts'), ('locality_name', 'Newbury'), ('organization_name', 'Codex Non Sufficit LC'), ('organizational_unit_name', 'Testing'), ('common_name', 'Will Bond'), ('email_address', '*****@*****.**'), ])), ('serial_number', 13683582341504654466) ]), signer['sid'].native) self.assertEqual( util.OrderedDict([ ('algorithm', 'sha256'), ('parameters', None), ]), signer['digest_algorithm'].native) signed_attrs = signer['signed_attrs'] self.assertEqual(4, len(signed_attrs)) self.assertEqual('content_type', signed_attrs[0]['type'].native) self.assertEqual('data', signed_attrs[0]['values'][0].native) self.assertEqual('signing_time', signed_attrs[1]['type'].native) self.assertEqual( datetime(2015, 6, 3, 5, 55, 12, tzinfo=util.timezone.utc), signed_attrs[1]['values'][0].native) self.assertEqual('message_digest', signed_attrs[2]['type'].native) self.assertEqual( b'\x52\x88\x25\x47\x15\x5B\x2D\x50\x44\x68\x05\x24\xC8\x71\x5A\xCC\x62\x28\x36\x17\xB7\x68' b'\xEE\xA1\x12\x90\x96\x4F\x94\xAE\xDB\x79', signed_attrs[2]['values'][0].native) self.assertEqual( util.OrderedDict([ ('algorithm', 'rsassa_pkcs1v15'), ('parameters', None), ]), signer['signature_algorithm'].native) self.assertEqual( b'\x43\x66\xEE\xF4\x6A\x02\x6F\xFE\x0D\xAE\xE6\xF3\x7A\x8F\x2C\x8E\x26\xB6\x25\x68\xEF\x5B' b'\x4B\x4F\x9C\xE4\xE6\x71\x42\x22\xEC\x97\xFC\x53\xD9\xD6\x36\x1F\xA1\x32\x35\xFF\xA9\x95' b'\x45\x50\x36\x36\x0C\x9A\x10\x6F\x06\xB6\x9D\x25\x10\x08\xF5\xF4\xE1\x68\x62\x60\xE5\xBF' b'\xBD\xE2\x9F\xBD\x8A\x10\x29\x3B\xAF\xE7\xD6\x55\x7C\xEE\x3B\xFB\x93\x42\xE0\xB4\x4F\x89' b'\xD0\x7B\x18\x51\x85\x90\x47\xF0\x5E\xE1\x15\x2C\xC1\x9A\xF1\x49\xE8\x11\x29\x17\x2E\x77' b'\xD3\x35\x10\xAA\xCD\x32\x07\x32\x74\xCF\x2D\x89\xBD\xEF\xC7\xC9\xE7\xEC\x90\x44\xCE\x0B' b'\xC5\x97\x00\x26\x67\x8A\x89\x5B\xFA\x46\xB2\x92\xD5\xCB\xA3\x52\x16\xDC\xF0\xF0\x79\xCB' b'\x90\x93\x8E\x26\xB3\xEB\x8F\xBD\x54\x06\xD6\xB0\xA0\x04\x47\x7C\x63\xFC\x88\x5A\xE3\x81' b'\xDF\x1E\x4D\x39\xFD\xF5\xA0\xE2\xD3\xAB\x13\xC1\xCF\x50\xB2\x0B\xC9\x36\xD6\xCB\xEA\x55' b'\x39\x97\x8E\x34\x47\xE3\x6B\x44\x4A\x0E\x03\xAF\x41\xB2\x47\x2E\x26\xA3\x6B\x5F\xA1\x5C' b'\x86\xA1\x96\x37\x02\xD3\x7C\x5F\xC1\xAF\x81\xE4\x1A\xD9\x87\x44\xB5\xB3\x5C\x45\x6C\xFF' b'\x97\x4C\x3A\xB4\x2F\x5C\x2F\x86\x15\x51\x71\xA6\x27\x68', signer['signature'].native)
def test_parse_content_info_cms_signed_data(self): with open(os.path.join(fixtures_dir, 'cms-signed.der'), 'rb') as f: info = cms.ContentInfo.load(f.read()) signed_data = info['content'] encap_content_info = signed_data['encap_content_info'] self.assertEqual('signed_data', info['content_type'].native) self.assertEqual('v1', signed_data['version'].native) self.assertEqual([ util.OrderedDict([ ('algorithm', 'sha256'), ('parameters', None), ]) ], signed_data['digest_algorithms'].native) self.assertEqual('data', encap_content_info['content_type'].native) self.assertEqual( b'This is the message to encapsulate in PKCS#7/CMS\r\n', encap_content_info['content'].native) self.assertEqual(1, len(signed_data['certificates'])) certificate = signed_data['certificates'][0] with open(os.path.join(fixtures_dir, 'keys/test-der.crt'), 'rb') as f: self.assertEqual(f.read(), certificate.dump()) self.assertEqual(1, len(signed_data['signer_infos'])) signer = signed_data['signer_infos'][0] self.assertEqual('v1', signer['version'].native) self.assertEqual( util.OrderedDict([ ('issuer', util.OrderedDict([ ('country_name', 'US'), ('state_or_province_name', 'Massachusetts'), ('locality_name', 'Newbury'), ('organization_name', 'Codex Non Sufficit LC'), ('organizational_unit_name', 'Testing'), ('common_name', 'Will Bond'), ('email_address', '*****@*****.**'), ])), ('serial_number', 13683582341504654466) ]), signer['sid'].native) self.assertEqual( util.OrderedDict([ ('algorithm', 'sha256'), ('parameters', None), ]), signer['digest_algorithm'].native) signed_attrs = signer['signed_attrs'] self.assertEqual(3, len(signed_attrs)) self.assertEqual('content_type', signed_attrs[0]['type'].native) self.assertEqual('data', signed_attrs[0]['values'][0].native) self.assertEqual('signing_time', signed_attrs[1]['type'].native) self.assertEqual( datetime(2015, 5, 30, 13, 12, 38, tzinfo=util.timezone.utc), signed_attrs[1]['values'][0].native) self.assertEqual('message_digest', signed_attrs[2]['type'].native) self.assertEqual( b'\xA1\x30\xE2\x87\x90\x5A\x58\x15\x7A\x44\x54\x7A\xB9\xBC\xAE\xD3\x00\xF3\xEC\x3E\x97\xFF' b'\x03\x20\x79\x34\x9D\x62\xAA\x20\xA5\x1D', signed_attrs[2]['values'][0].native) self.assertEqual( util.OrderedDict([ ('algorithm', 'rsassa_pkcs1v15'), ('parameters', None), ]), signer['signature_algorithm'].native) self.assertEqual( b'\xAC\x2F\xE3\x25\x39\x8F\xD3\xDF\x80\x4F\x0D\xBA\xB1\xEE\x99\x09\xA9\x21\xBB\xDF\x3C\x1E' b'\x70\xDA\xDF\xC4\x0F\x1D\x10\x29\xBC\x94\xBE\xF8\xA8\xC2\x2D\x2A\x1F\x14\xBC\x4A\x5B\x66' b'\x7F\x6F\xE4\xDF\x82\x4D\xD9\x3F\xEB\x89\xAA\x05\x1A\xE5\x58\xCE\xC4\x33\x53\x6E\xE4\x66' b'\xF9\x21\xCF\x80\x35\x46\x88\xB5\x6A\xEA\x5C\x54\x49\x40\x31\xD6\xDC\x20\xD8\xA0\x63\x8C' b'\xC1\xC3\xA1\x72\x5D\x0D\xCE\x43\xB1\x5C\xD8\x32\x3F\xA9\xE7\xBB\xD9\x56\xAE\xE7\xFB\x7C' b'\x37\x32\x8B\x93\xC2\xC4\x47\xDD\x00\xFB\x1C\xEF\xC3\x68\x32\xDC\x06\x26\x17\x45\xF5\xB3' b'\xDC\xD8\x5C\x2B\xC1\x8B\x97\x93\xB8\xF1\x85\xE2\x92\x3B\xC4\x6A\x6A\x89\xC5\x14\x51\x4A' b'\x06\x11\x54\xB0\x29\x07\x75\xD8\xDF\x6B\xFB\x21\xE4\xA4\x09\x17\xAF\xAC\xA0\xF5\xC0\xFE' b'\x7B\x03\x04\x40\x41\x57\xC4\xFD\x58\x1D\x10\x5E\xAC\x23\xAB\xAA\x80\x95\x96\x02\x71\x84' b'\x9C\x0A\xBD\x54\xC4\xA2\x47\xAA\xE7\xC3\x09\x13\x6E\x26\x7D\x72\xAA\xA9\x0B\xF3\xCC\xC4' b'\x48\xB4\x97\x14\x00\x47\x2A\x6B\xD3\x93\x3F\xD8\xFD\xAA\xB9\xFB\xFB\xD5\x09\x8D\x82\x8B' b'\xDE\x0F\xED\x39\x6D\x7B\xDC\x76\x8B\xA6\x4E\x9B\x7A\xBA', signer['signature'].native)
def test_parse_content_info_enveloped_data(self): with open(os.path.join(fixtures_dir, 'cms-enveloped.der'), 'rb') as f: info = cms.ContentInfo.load(f.read()) enveloped_data = info['content'] encrypted_content_info = enveloped_data['encrypted_content_info'] recipient = enveloped_data['recipient_infos'][0].chosen self.assertEqual('enveloped_data', info['content_type'].native) self.assertEqual('v0', enveloped_data['version'].native) self.assertEqual(None, enveloped_data['originator_info'].native) self.assertEqual(1, len(enveloped_data['recipient_infos'])) self.assertEqual('v0', recipient['version'].native) self.assertEqual( util.OrderedDict([ ('issuer', util.OrderedDict([ ('country_name', 'US'), ('state_or_province_name', 'Massachusetts'), ('locality_name', 'Newbury'), ('organization_name', 'Codex Non Sufficit LC'), ('organizational_unit_name', 'Testing'), ('common_name', 'Will Bond'), ('email_address', '*****@*****.**'), ])), ('serial_number', 13683582341504654466) ]), recipient['rid'].native) self.assertEqual( 'rsaes_pkcs1v15', recipient['key_encryption_algorithm']['algorithm'].native) self.assertEqual( None, recipient['key_encryption_algorithm']['parameters'].native) self.assertEqual( b'\x97\x0A\xFD\x3B\x5C\x27\x45\x69\xCC\xDD\x45\x9E\xA7\x3C\x07\x27\x35\x16\x20\x21\xE4\x6E\x1D\xF8' b'\x5B\xE8\x7F\xD8\x40\x41\xE9\xF2\x92\xCD\xC8\xC5\x03\x95\xEC\x6C\x0B\x97\x71\x87\x86\x3C\xEB\x68' b'\x84\x06\x4E\xE6\xD0\xC4\x7D\x32\xFE\xA6\x06\xC9\xD5\xE1\x8B\xDA\xBF\x96\x5C\x20\x15\x49\x64\x7A' b'\xA2\x4C\xFF\x8B\x0D\xEA\x76\x35\x9B\x7C\x43\xF7\x21\x95\x26\xE7\x70\x30\x98\x5F\x0D\x5E\x4A\xCB' b'\xAD\x47\xDF\x46\xDA\x1F\x0E\xE2\xFE\x3A\x40\xD9\xF2\xDC\x0C\x97\xD9\x91\xED\x34\x8D\xF3\x73\xB0' b'\x90\xF9\xDD\x31\x4D\x37\x93\x81\xD3\x92\xCB\x72\x4A\xD6\x9D\x01\x82\x85\xD5\x1F\xE2\xAA\x32\x12' b'\x82\x4E\x17\xF6\xAA\x58\xDE\xBD\x1B\x80\xAF\x61\xF1\x8A\xD1\x7F\x9D\x41\x6A\xC0\xE4\xC7\x7E\x17' b'\xDC\x94\x33\xE9\x74\x7E\xE9\xF8\x5C\x30\x87\x9B\xD6\xF0\xE3\x4A\xB7\xE3\xCC\x51\x8A\xD4\x37\xF1' b'\xF9\x33\xB5\xD6\x1F\x36\xC1\x6F\x91\xA8\x5F\xE2\x6B\x08\xC7\x9D\xE8\xFD\xDC\xE8\x78\xE0\xC0\xC7' b'\xCF\xC5\xEE\x60\xEC\x54\xFF\x1A\x9C\xF7\x4E\x2C\xD0\x88\xDC\xC2\x1F\xDC\x8A\x37\x9B\x71\x20\xFF' b'\xFD\x6C\xE5\xBA\x8C\xDF\x0E\x3F\x20\xC6\xCB\x08\xA7\x07\xDB\x83', recipient['encrypted_key'].native) self.assertEqual('data', encrypted_content_info['content_type'].native) self.assertEqual( 'tripledes_3key', encrypted_content_info['content_encryption_algorithm'] ['algorithm'].native) self.assertEqual( 'tripledes', encrypted_content_info['content_encryption_algorithm']. encryption_cipher) self.assertEqual( 'cbc', encrypted_content_info['content_encryption_algorithm']. encryption_mode) self.assertEqual( 24, encrypted_content_info['content_encryption_algorithm'].key_length) self.assertEqual( 8, encrypted_content_info['content_encryption_algorithm']. encryption_block_size) self.assertEqual( b'\x52\x50\x98\xFA\x33\x88\xC7\x3C', encrypted_content_info['content_encryption_algorithm'] ['parameters'].native) self.assertEqual( b'\xDC\x88\x55\x08\xE5\x67\x70\x49\x99\x54\xFD\xF8\x40\x7C\x38\xD5\x78\x1D\x6A\x95\x6D\x1E\xC4\x12' b'\x39\xFE\xC0\x76\xDC\xF5\x79\x1A\x69\xA1\xB9\x40\x1E\xCF\xC8\x79\x3E\xF3\x38\xB4\x90\x00\x27\xD1' b'\xB5\x64\xAB\x99\x51\x13\xF1\x0A', encrypted_content_info['encrypted_content'].native) self.assertEqual(None, enveloped_data['unprotected_attrs'].native)
def test_parse_response(self): with open(os.path.join(fixtures_dir, 'tsp_response'), 'rb') as f: response = tsp.TimeStampResp.load(f.read()) status_info = response['status'] token = response['time_stamp_token'] signed_data = token['content'] encap_content_info = signed_data['encap_content_info'] tst_info = encap_content_info['content'].parsed signer_infos = signed_data['signer_infos'] signer_info = signer_infos[0] signed_attrs = signer_info['signed_attrs'] self.assertEqual('granted', status_info['status'].native) self.assertEqual(None, status_info['status_string'].native) self.assertEqual(None, status_info['fail_info'].native) self.assertEqual('signed_data', token['content_type'].native) self.assertIsInstance(signed_data, cms.SignedData) self.assertEqual('v3', signed_data['version'].native) self.assertEqual( 'sha1', signed_data['digest_algorithms'][0]['algorithm'].native) self.assertEqual('tst_info', encap_content_info['content_type'].native) self.assertIsInstance(tst_info, tsp.TSTInfo) self.assertEqual('v1', tst_info['version'].native) self.assertEqual('1.1.2', tst_info['policy'].native) self.assertEqual( 'sha1', tst_info['message_imprint']['hash_algorithm']['algorithm'].native) self.assertEqual( None, tst_info['message_imprint']['hash_algorithm']['parameters'].native) self.assertEqual( b'\x53\xC9\xDB\xC1\x6D\xDB\x34\x3B\x28\x4E\xEF\xA6\x03\x0E\x02\x64\x79\x31\xAF\xFB', tst_info['message_imprint']['hashed_message'].native) self.assertEqual(544918635, tst_info['serial_number'].native) self.assertEqual( datetime(2015, 6, 1, 18, 39, 55, tzinfo=util.timezone.utc), tst_info['gen_time'].native) self.assertEqual(60, tst_info['accuracy']['seconds'].native) self.assertEqual(None, tst_info['accuracy']['millis'].native) self.assertEqual(None, tst_info['accuracy']['micros'].native) self.assertEqual(False, tst_info['ordering'].native) self.assertEqual(17842879675353045770, tst_info['nonce'].native) self.assertEqual( util.OrderedDict([ ('country_name', 'US'), ('organization_name', 'GeoTrust Inc'), ('common_name', 'GeoTrust Timestamping Signer 1'), ]), tst_info['tsa'].native) self.assertEqual(None, tst_info['extensions'].native) self.assertEqual(None, signed_data['certificates'].native) self.assertEqual(None, signed_data['crls'].native) self.assertEqual(1, len(signer_infos)) self.assertEqual('v1', signer_info['version'].native) self.assertEqual( util.OrderedDict([ ('issuer', util.OrderedDict([ ('country_name', 'ZA'), ('state_or_province_name', 'Western Cape'), ('locality_name', 'Durbanville'), ('organization_name', 'Thawte'), ('organizational_unit_name', 'Thawte Certification'), ('common_name', 'Thawte Timestamping CA'), ])), ('serial_number', 125680471847352264461591953321128732863) ]), signer_info['sid'].native) self.assertEqual('sha1', signer_info['digest_algorithm']['algorithm'].native) self.assertEqual(4, len(signed_attrs)) self.assertEqual('content_type', signed_attrs[0]['type'].native) self.assertEqual('tst_info', signed_attrs[0]['values'][0].native) self.assertEqual('signing_time', signed_attrs[1]['type'].native) self.assertEqual( datetime(2015, 6, 1, 18, 39, 55, tzinfo=util.timezone.utc), signed_attrs[1]['values'][0].native) self.assertEqual('message_digest', signed_attrs[2]['type'].native) self.assertEqual( b'\x22\x06\x7D\xA4\xFC\x7B\xC5\x94\x80\xB4\xB0\x78\xC2\x07\x66\x02\xA3\x0D\x62\xAE', signed_attrs[2]['values'][0].native) self.assertEqual('signing_certificate', signed_attrs[3]['type'].native) self.assertEqual( util.OrderedDict([('certs', [ util.OrderedDict([ ('cert_hash', b'\x22\x3C\xDA\x27\x07\x96\x73\x81\x6B\x60\x8A\x1B\x8C\xB0\xAB\x02\x30\x10\x7F\xCC' ), ('issuer_serial', None), ]) ]), ('policies', None)]), signed_attrs[3]['values'][0].native)
def sign_file( file_path, signature_file_path, certificate_file_path, private_key_file_path, dev_passphrase=None ): print( "Signing %s using %s certificate and %s private key" % (file_path, certificate_file_path, private_key_file_path) ) with open(private_key_file_path, "rb") as fp: private_key = serialization.load_pem_private_key( fp.read(), password=dev_passphrase.encode() if dev_passphrase else None, backend=default_backend() ) sha256 = hashes.SHA256() hasher = hashes.Hash(sha256) with open(file_path, "rb") as fp: buf = fp.read(CHUNK_SIZE) while len(buf) > 0: hasher.update(buf) buf = fp.read(CHUNK_SIZE) signature = private_key.sign( hasher.finalize(), padding.PKCS1v15(), utils.Prehashed(sha256) ) signed_data = cms.SignedData() signed_data["version"] = "v1" signed_data["encap_content_info"] = util.OrderedDict( [("content_type", "data"), ("content", None)] ) signed_data["digest_algorithms"] = [ util.OrderedDict([("algorithm", "sha256"), ("parameters", None)]) ] with open(certificate_file_path, "rb") as fp: der_bytes = fp.read() if pem.detect(der_bytes): type_name, headers, der_bytes = pem.unarmor(der_bytes) else: print("Wrong certificate format, expected PEM, aborting!") raise dtcliutils.ExtensionBuildError() cert = x509.Certificate.load(der_bytes) signed_data["certificates"] = [ cert, ] signer_info = cms.SignerInfo() signer_info["version"] = 1 signer_info["digest_algorithm"] = util.OrderedDict( [("algorithm", "sha256"), ("parameters", None)] ) signer_info["signature_algorithm"] = util.OrderedDict( [("algorithm", "rsassa_pkcs1v15"), ("parameters", core.Null)] ) signer_info["signature"] = signature signer_info["sid"] = cms.SignerIdentifier( { "issuer_and_serial_number": util.OrderedDict( [ ("issuer", cert.issuer), ("serial_number", cert.serial_number), ] ) } ) signed_data["signer_infos"] = [ signer_info, ] # TODO timestamping? # dump ASN.1 object asn1obj = cms.ContentInfo() asn1obj["content_type"] = "signed_data" asn1obj["content"] = signed_data with open(signature_file_path, "wb+") as fp: der_bytes = asn1obj.dump() pem_bytes = pem.armor("CMS", der_bytes) fp.write(pem_bytes) print("Wrote signature file %s" % signature_file_path)
def _cms_signature(self, zulu: datetime, data: bytes) -> bytes: """Sign provided data and return CMS signature. :param zulu: current UTC time+date :param data: to be signed :return: CMS signature (binary) """ assert self.certificate is not None assert self.private_key_pem_data is not None # signed data (main section) signed_data = cms.SignedData() signed_data['version'] = 'v1' signed_data['encap_content_info'] = util.OrderedDict([ ('content_type', 'data') ]) signed_data['digest_algorithms'] = [util.OrderedDict([ ('algorithm', 'sha256'), ('parameters', None)])] # signer info sub-section signer_info = cms.SignerInfo() signer_info['version'] = 'v1' signer_info['digest_algorithm'] = util.OrderedDict([ ('algorithm', 'sha256'), ('parameters', None)]) signer_info['signature_algorithm'] = util.OrderedDict([ ('algorithm', 'rsassa_pkcs1v15'), ('parameters', b'')]) # signed identifier: issuer amd serial number asn1cert = x509.Certificate.load(self.certificate.public_bytes(Encoding.DER)) signer_info['sid'] = cms.SignerIdentifier({ 'issuer_and_serial_number': cms.IssuerAndSerialNumber({ 'issuer': asn1cert.issuer, 'serial_number': asn1cert.serial_number }) }) # signed attributes signed_attrs = cms.CMSAttributes() signed_attrs.append(cms.CMSAttribute({ 'type': 'content_type', 'values': [cms.ContentType('data')], })) # check time-zone is assigned (expected UTC+0) assert zulu.tzinfo signed_attrs.append(cms.CMSAttribute({ 'type': 'signing_time', 'values': [cms.Time(name='utc_time', value=zulu.strftime('%y%m%d%H%M%SZ'))], })) signed_attrs.append(cms.CMSAttribute({ 'type': 'message_digest', 'values': [cms.OctetString(crypto_backend().hash(data))], # digest })) signer_info['signed_attrs'] = signed_attrs # create signature signer_info['signature'] = crypto_backend().rsa_sign(self.private_key_pem_data, signed_attrs.dump()) # Adding SignerInfo object to SignedData object signed_data['signer_infos'] = [signer_info] # content info content_info = cms.ContentInfo() content_info['content_type'] = 'signed_data' content_info['content'] = signed_data return content_info.dump()