예제 #1
0
 def test_fix_tagging_choice(self):
     correct = core.Integer(200, tag_type='explicit', tag=2)
     choice = NumChoice(name='three',
                        value=core.Integer(200, tag_type='explicit', tag=1))
     self.assertEqual(correct.dump(), choice.dump())
     self.assertEqual(correct.tag_type, choice.chosen.tag_type)
     self.assertEqual(correct.explicit_tag, choice.chosen.explicit_tag)
예제 #2
0
 def test_fix_tagging_choice(self):
     correct = core.Integer(200, explicit=2)
     choice = NumChoice(name='three', value=core.Integer(200, explicit=1))
     self.assertEqual(correct.dump(), choice.dump())
     self.assertEqual(correct.explicit, choice.chosen.explicit)
     choice2 = NumChoiceOldApi(name='three',
                               value=core.Integer(200, explicit=1))
     self.assertEqual(correct.dump(), choice2.dump())
     self.assertEqual(correct.explicit, choice2.chosen.explicit)
예제 #3
0
 def format_tbs_crl(self, crl_number: int, this_update: datetime,
                    revoked_certs, next_update: datetime,
                    distpoint: x509.DistributionPoint = None) \
         -> crl.TbsCertList:
     extensions = [
         crl.TBSCertListExtension({
             'extn_id': 'crl_number', 'extn_value': core.Integer(crl_number)
         }),
         crl.TBSCertListExtension({
             'extn_id': 'authority_key_identifier',
             'extn_value': x509.AuthorityKeyIdentifier({
                 'key_identifier': self.authority_key_identifier
             })
         }),
     ]
     extensions.extend(self.extra_crl_extensions)
     if distpoint is not None:
         extn_value = crl.IssuingDistributionPoint(distpoint)
         extensions.append(
             crl.TBSCertListExtension({
                 'extn_id': 'issuing_distribution_point',
                 'critical': True,
                 'extn_value': core.ParsableOctetString(extn_value.dump())
             })
         )
     revoked = crl.RevokedCertificates(revoked_certs)
     return crl.TbsCertList({
         'version': 'v2',
         'signature': self.signature_algo,
         'issuer': self.issuer_name,
         'this_update': x509.Time({'general_time': this_update}),
         'next_update': x509.Time({'general_time': next_update}),
         'revoked_certificates': revoked,
         'crl_extensions': crl.TBSCertListExtensions(extensions)
     })
예제 #4
0
 def test_concat(self):
     child1 = Seq({'id': '1.2.3', 'value': 1})
     child2 = core.Integer(0)
     parent = ConcatTest([child1, child2])
     self.assertEqual(child1, parent[0])
     self.assertEqual(child2, parent[1])
     self.assertEqual(child1.dump() + child2.dump(), parent.dump())
def test_timestamp(requests_mock, setup):
    setup.illusionist.register(requests_mock)
    hashed_bytes = hashlib.sha256(b'test').digest()
    req = tsp.TimeStampReq({
        'version':
        'v2',
        'message_imprint':
        tsp.MessageImprint({
            'hash_algorithm':
            algos.DigestAlgorithm({'algorithm': 'sha256'}),
            'hashed_message':
            hashed_bytes
        }),
        'nonce':
        core.Integer(0x1337),
        'cert_req':
        True
    })
    response = requests.post("http://test.test/testing-ca/tsa/tsa",
                             data=req.dump())
    resp: tsp.TimeStampResp = tsp.TimeStampResp.load(response.content)
    sd = resp['time_stamp_token']['content']
    tst_info: tsp.TSTInfo = sd['encap_content_info']['content'].parsed
    assert tst_info['nonce'].native == 0x1337
    assert tst_info['gen_time'].native \
           == datetime.now().replace(tzinfo=pytz.utc)
예제 #6
0
def _unwrap_private_key_info(key_info):
    """
    Unwraps an asn1crypto.keys.PrivateKeyInfo object into an
    asn1crypto.keys.RSAPrivateKey, asn1crypto.keys.DSAPrivateKey
    or asn1crypto.keys.ECPrivateKey.

    :param key_info:
        An asn1crypto.keys.PrivateKeyInfo object

    :return:
        One of:
         - asn1crypto.keys.RSAPrivateKey
         - asn1crypto.keys.DSAPrivateKey
         - asn1crypto.keys.ECPrivateKey
    """

    if key_info.algorithm == 'rsa':
        return key_info['private_key'].parsed

    if key_info.algorithm == 'dsa':
        params = key_info['private_key_algorithm']['parameters']
        parsed = key_info['private_key'].parsed
        return keys.DSAPrivateKey({
            'version':
            0,
            'p':
            params['p'],
            'q':
            params['q'],
            'g':
            params['g'],
            'public_key':
            core.Integer(
                pow(params['g'].native, parsed.native, params['p'].native)),
            'private_key':
            parsed,
        })

    if key_info.algorithm == 'ec':
        parsed = key_info['private_key'].parsed
        parsed['parameters'] = key_info['private_key_algorithm']['parameters']
        return parsed

    raise ValueError('Unsupported key_info.algorithm "%s"' %
                     key_info.algorithm)
예제 #7
0
 def compare_primitive_info():
     return (
         (core.ObjectIdentifier('1.2.3'), core.ObjectIdentifier('1.2.3'),
          True),
         (core.Integer(1), Enum(1), False),
         (core.Integer(1), core.Integer(1, implicit=5), True),
         (core.Integer(1), core.Integer(1, explicit=5), True),
         (core.Integer(1), core.Integer(2), False),
         (core.OctetString(b''), core.OctetString(b''), True),
         (core.OctetString(b''), core.OctetString(b'1'), False),
         (core.OctetString(b''), core.OctetBitString(b''), False),
         (core.ParsableOctetString(b'12'), core.OctetString(b'12'), True),
         (core.ParsableOctetBitString(b'12'), core.OctetBitString(b'12'),
          True),
         (core.UTF8String('12'), core.UTF8String('12'), True),
         (core.UTF8String('12'), core.UTF8String('1'), False),
         (core.UTF8String('12'), core.IA5String('12'), False),
     )
예제 #8
0
 def test_wrong_asn1value2(self):
     with self.assertRaises(TypeError):
         CopySeq({'name': core.UTF8String('Test'), 'pair': core.Integer(1)})
예제 #9
0
 def test_untag(self):
     a = core.Integer(200, explicit=0)
     b = a.untag()
     self.assertNotEqual(id(a), id(b))
     self.assertEqual(a.contents, b.contents)
     self.assertNotEqual(a.dump(), b.dump())
예제 #10
0
 def test_retag(self):
     a = core.Integer(200)
     b = a.retag('explicit', 0)
     self.assertNotEqual(id(a), id(b))
     self.assertEqual(a.contents, b.contents)
     self.assertNotEqual(a.dump(), b.dump())
예제 #11
0
 def test_copy(self):
     a = core.Integer(200)
     b = a.copy()
     self.assertNotEqual(id(a), id(b))
     self.assertEqual(a.contents, b.contents)
     self.assertEqual(a.dump(), b.dump())
예제 #12
0
 def test_sequence_any_asn1value(self):
     seq = SequenceAny()
     seq.append(core.Integer(5))
     self.assertEqual([5], seq.native)
예제 #13
0
 def test_sequece_choice_choice(self):
     CCSeq({'cc': ChoiceChoice('num', NumChoice('one', core.Integer(0)))})
예제 #14
0
 def integer(self, native, der_bytes):
     i = core.Integer(native)
     self.assertEqual(der_bytes, i.dump())
     self.assertEqual(native, core.Integer.load(der_bytes).native)
예제 #15
0
def _fingerprint(key_object, load_private_key):
    """
    Returns a fingerprint used for correlating public keys and private keys

    :param key_object:
        An asn1crypto.keys.PrivateKeyInfo or asn1crypto.keys.PublicKeyInfo

    :raises:
        ValueError - when the key_object is not of the proper type

    ;return:
        A byte string fingerprint
    """

    if isinstance(key_object, keys.PrivateKeyInfo):
        key = key_object['private_key'].parsed

        if key_object.algorithm == 'rsa':
            to_hash = '%d:%d' % (
                key['modulus'].native,
                key['public_exponent'].native,
            )

        elif key_object.algorithm == 'dsa':
            params = key_object['private_key_algorithm']['parameters']
            public_key = core.Integer(
                pow(params['g'].native,
                    key_object['private_key'].parsed.native,
                    params['p'].native))

            to_hash = '%d:%d:%d:%d' % (
                params['p'].native,
                params['q'].native,
                params['g'].native,
                public_key.native,
            )

        elif key_object.algorithm == 'ec':
            public_key = key['public_key'].native
            if public_key is None:
                # This is gross, but since the EC public key is optional,
                # and we need to load the private key and use the crypto lib
                # to get the public key, we have to import the platform-specific
                # asymmetric implementation. This is the reason a bunch of the
                # imports are module imports, so we don't get an import cycle.
                public_key_object = load_private_key(key_object).public_key
                public_key = public_key_object.asn1['public_key'].parsed.native

            to_hash = '%s:' % key_object.curve[1]
            to_hash = to_hash.encode('utf-8')
            to_hash += public_key

        if isinstance(to_hash, str_cls):
            to_hash = to_hash.encode('utf-8')

        return hashlib.sha256(to_hash).digest()

    if isinstance(key_object, keys.PublicKeyInfo):
        if key_object.algorithm == 'rsa':
            key = key_object['public_key'].parsed

            to_hash = '%d:%d' % (
                key['modulus'].native,
                key['public_exponent'].native,
            )

        elif key_object.algorithm == 'dsa':
            key = key_object['public_key'].parsed
            params = key_object['algorithm']['parameters']

            to_hash = '%d:%d:%d:%d' % (
                params['p'].native,
                params['q'].native,
                params['g'].native,
                key.native,
            )

        elif key_object.algorithm == 'ec':
            public_key = key_object['public_key'].native

            to_hash = '%s:' % key_object.curve[1]
            to_hash = to_hash.encode('utf-8')
            to_hash += public_key

        if isinstance(to_hash, str_cls):
            to_hash = to_hash.encode('utf-8')

        return hashlib.sha256(to_hash).digest()

    raise ValueError(
        pretty_message(
            '''
        key_object must be an instance of the
        asn1crypto.keys.PrivateKeyInfo or asn1crypto.keys.PublicKeyInfo
        classes, not %s
        ''', type_name(key_object)))
예제 #16
0
 def test_wrong_asn1value3(self):
     with self.assertRaises(TypeError):
         NestSeqAny({'id': '2.3.4.5', 'value': core.Integer(1)})
예제 #17
0
 def test_wrong_asn1value(self):
     with self.assertRaises(TypeError):
         Seq({'id': core.Integer(1), 'value': 1})
예제 #18
0
def sign_message(
    data_to_sign,
    digest_alg,
    sign_key,
    sign_alg="rsassa_pkcs1v15",
    use_signed_attributes=True,
):
    """Function signs the data and returns the generated ASN.1

    :param data_to_sign: A byte string of the data to be signed.

    :param digest_alg: The digest algorithm to be used for generating the signature.

    :param sign_key: The key to be used for generating the signature.

    :param sign_alg: The algorithm to be used for signing the message.

    :param use_signed_attributes: Optional attribute to indicate weather the
    CMS signature attributes should be included in the signature or not.

    :return: A CMS ASN.1 byte string of the signed data.
    """
    if use_signed_attributes:
        digest_func = hashlib.new(digest_alg)
        digest_func.update(data_to_sign)
        message_digest = digest_func.digest()

        class SmimeCapability(core.Sequence):
            _fields = [
                ("0", core.Any, {
                    "optional": True
                }),
                ("1", core.Any, {
                    "optional": True
                }),
                ("2", core.Any, {
                    "optional": True
                }),
                ("3", core.Any, {
                    "optional": True
                }),
                ("4", core.Any, {
                    "optional": True
                }),
            ]

        class SmimeCapabilities(core.Sequence):
            _fields = [
                ("0", SmimeCapability),
                ("1", SmimeCapability, {
                    "optional": True
                }),
                ("2", SmimeCapability, {
                    "optional": True
                }),
                ("3", SmimeCapability, {
                    "optional": True
                }),
                ("4", SmimeCapability, {
                    "optional": True
                }),
                ("5", SmimeCapability, {
                    "optional": True
                }),
            ]

        smime_cap = OrderedDict([
            (
                "0",
                OrderedDict([
                    ("0", core.ObjectIdentifier("2.16.840.1.101.3.4.1.42"))
                ]),
            ),
            (
                "1",
                OrderedDict([
                    ("0", core.ObjectIdentifier("2.16.840.1.101.3.4.1.2"))
                ]),
            ),
            (
                "2",
                OrderedDict([("0", core.ObjectIdentifier("1.2.840.113549.3.7"))
                             ]),
            ),
            (
                "3",
                OrderedDict([
                    ("0", core.ObjectIdentifier("1.2.840.113549.3.2")),
                    ("1", core.Integer(128)),
                ]),
            ),
            (
                "4",
                OrderedDict([
                    ("0", core.ObjectIdentifier("1.2.840.113549.3.4")),
                    ("1", core.Integer(128)),
                ]),
            ),
        ])

        signed_attributes = cms.CMSAttributes([
            cms.CMSAttribute({
                "type":
                cms.CMSAttributeType("content_type"),
                "values":
                cms.SetOfContentType([cms.ContentType("data")]),
            }),
            cms.CMSAttribute({
                "type":
                cms.CMSAttributeType("signing_time"),
                "values":
                cms.SetOfTime([
                    cms.Time({
                        "utc_time":
                        core.UTCTime(
                            datetime.utcnow().replace(tzinfo=timezone.utc))
                    })
                ]),
            }),
            cms.CMSAttribute({
                "type":
                cms.CMSAttributeType("message_digest"),
                "values":
                cms.SetOfOctetString([core.OctetString(message_digest)]),
            }),
            cms.CMSAttribute({
                "type":
                cms.CMSAttributeType("1.2.840.113549.1.9.15"),
                "values":
                cms.SetOfAny([core.Any(SmimeCapabilities(smime_cap))]),
            }),
        ])
    else:
        signed_attributes = None

    # Generate the signature
    data_to_sign = signed_attributes.dump(
    ) if signed_attributes else data_to_sign
    if sign_alg == "rsassa_pkcs1v15":
        signature = asymmetric.rsa_pkcs1v15_sign(sign_key[0], data_to_sign,
                                                 digest_alg)
    elif sign_alg == "rsassa_pss":
        signature = asymmetric.rsa_pss_sign(sign_key[0], data_to_sign,
                                            digest_alg)
    else:
        raise AS2Exception("Unsupported Signature Algorithm")

    return cms.ContentInfo({
        "content_type":
        cms.ContentType("signed_data"),
        "content":
        cms.SignedData({
            "version":
            cms.CMSVersion("v1"),
            "digest_algorithms":
            cms.DigestAlgorithms([
                algos.DigestAlgorithm(
                    {"algorithm": algos.DigestAlgorithmId(digest_alg)})
            ]),
            "encap_content_info":
            cms.ContentInfo({"content_type": cms.ContentType("data")}),
            "certificates":
            cms.CertificateSet(
                [cms.CertificateChoices({"certificate": sign_key[1].asn1})]),
            "signer_infos":
            cms.SignerInfos([
                cms.SignerInfo({
                    "version":
                    cms.CMSVersion("v1"),
                    "sid":
                    cms.SignerIdentifier({
                        "issuer_and_serial_number":
                        cms.IssuerAndSerialNumber({
                            "issuer":
                            sign_key[1].asn1["tbs_certificate"]["issuer"],
                            "serial_number":
                            sign_key[1].asn1["tbs_certificate"]
                            ["serial_number"],
                        })
                    }),
                    "digest_algorithm":
                    algos.DigestAlgorithm(
                        {"algorithm": algos.DigestAlgorithmId(digest_alg)}),
                    "signed_attrs":
                    signed_attributes,
                    "signature_algorithm":
                    algos.SignedDigestAlgorithm(
                        {"algorithm":
                         algos.SignedDigestAlgorithmId(sign_alg)}),
                    "signature":
                    core.OctetString(signature),
                })
            ]),
        }),
    }).dump()
예제 #19
0
def sign_message(data_to_sign,
                 digest_alg,
                 sign_key,
                 use_signed_attributes=True):
    """Function signs the data and returns the generated ASN.1

    :param data_to_sign: A byte string of the data to be signed.

    :param digest_alg: 
        The digest algorithm to be used for generating the signature.

    :param sign_key: The key to be used for generating the signature.
    
    :param use_signed_attributes: Optional attribute to indicate weather the 
    CMS signature attributes should be included in the signature or not.

    :return: A CMS ASN.1 byte string of the signed data.    
    """
    if use_signed_attributes:
        digest_func = hashlib.new(digest_alg)
        digest_func.update(data_to_sign)
        message_digest = digest_func.digest()

        class SmimeCapability(core.Sequence):
            _fields = [('0', core.Any, {
                'optional': True
            }), ('1', core.Any, {
                'optional': True
            }), ('2', core.Any, {
                'optional': True
            }), ('3', core.Any, {
                'optional': True
            }), ('4', core.Any, {
                'optional': True
            })]

        class SmimeCapabilities(core.Sequence):
            _fields = [
                ('0', SmimeCapability),
                ('1', SmimeCapability, {
                    'optional': True
                }),
                ('2', SmimeCapability, {
                    'optional': True
                }),
                ('3', SmimeCapability, {
                    'optional': True
                }),
                ('4', SmimeCapability, {
                    'optional': True
                }),
                ('5', SmimeCapability, {
                    'optional': True
                }),
            ]

        smime_cap = OrderedDict([
            ('0',
             OrderedDict([('0', core.ObjectIdentifier('1.2.840.113549.3.7'))
                          ])),
            ('1',
             OrderedDict([('0', core.ObjectIdentifier('1.2.840.113549.3.2')),
                          ('1', core.Integer(128))])),
            ('2',
             OrderedDict([('0', core.ObjectIdentifier('1.2.840.113549.3.4')),
                          ('1', core.Integer(128))])),
        ])

        signed_attributes = cms.CMSAttributes([
            cms.CMSAttribute({
                'type':
                cms.CMSAttributeType('content_type'),
                'values':
                cms.SetOfContentType([cms.ContentType('data')])
            }),
            cms.CMSAttribute({
                'type':
                cms.CMSAttributeType('signing_time'),
                'values':
                cms.SetOfTime(
                    [cms.Time({'utc_time': core.UTCTime(datetime.now())})])
            }),
            cms.CMSAttribute({
                'type':
                cms.CMSAttributeType('message_digest'),
                'values':
                cms.SetOfOctetString([core.OctetString(message_digest)])
            }),
            cms.CMSAttribute({
                'type':
                cms.CMSAttributeType('1.2.840.113549.1.9.15'),
                'values':
                cms.SetOfAny([core.Any(SmimeCapabilities(smime_cap))])
            }),
        ])
        signature = asymmetric.rsa_pkcs1v15_sign(sign_key[0],
                                                 signed_attributes.dump(),
                                                 digest_alg)
    else:
        signed_attributes = None
        signature = asymmetric.rsa_pkcs1v15_sign(sign_key[0], data_to_sign,
                                                 digest_alg)

    return cms.ContentInfo({
        'content_type':
        cms.ContentType('signed_data'),
        'content':
        cms.SignedData({
            'version':
            cms.CMSVersion('v1'),
            'digest_algorithms':
            cms.DigestAlgorithms([
                algos.DigestAlgorithm(
                    {'algorithm': algos.DigestAlgorithmId(digest_alg)})
            ]),
            'encap_content_info':
            cms.ContentInfo({'content_type': cms.ContentType('data')}),
            'certificates':
            cms.CertificateSet(
                [cms.CertificateChoices({'certificate': sign_key[1].asn1})]),
            'signer_infos':
            cms.SignerInfos([
                cms.SignerInfo({
                    'version':
                    cms.CMSVersion('v1'),
                    'sid':
                    cms.SignerIdentifier({
                        'issuer_and_serial_number':
                        cms.IssuerAndSerialNumber({
                            'issuer':
                            sign_key[1].asn1['tbs_certificate']['issuer'],
                            'serial_number':
                            sign_key[1].asn1['tbs_certificate']
                            ['serial_number']
                        })
                    }),
                    'digest_algorithm':
                    algos.DigestAlgorithm(
                        {'algorithm': algos.DigestAlgorithmId(digest_alg)}),
                    'signed_attrs':
                    signed_attributes,
                    'signature_algorithm':
                    algos.SignedDigestAlgorithm({
                        'algorithm':
                        algos.SignedDigestAlgorithmId('rsassa_pkcs1v15')
                    }),
                    'signature':
                    core.OctetString(signature)
                })
            ])
        })
    }).dump()
예제 #20
0
 def test_required_field(self):
     with self.assertRaisesRegexp(ValueError,
                                  '"id" is missing from structure'):
         Seq({'value': core.Integer(5)}).dump()
예제 #21
0
 def test_wrong_asn1value4(self):
     with self.assertRaises(TypeError):
         NestSeqExplicit({'id': '3.4.5', 'value': core.Integer(1)})