Ejemplo n.º 1
0
    def recipient_info(self, cert, session_key):
        public_key = cert.get_pubkey().to_cryptography_key()
        encrypted_key = public_key.encrypt(session_key, padding.PKCS1v15())
        cert = signer.cert2asn(cert.to_cryptography())

        tbs_cert = cert['tbs_certificate']
        # TODO: use subject_key_identifier when available
        return cms.RecipientInfo(name=u'ktri',
                                 value={
                                     'version':
                                     u'v0',
                                     'rid':
                                     cms.RecipientIdentifier(
                                         name=u'issuer_and_serial_number',
                                         value={
                                             'issuer':
                                             tbs_cert['issuer'],
                                             'serial_number':
                                             tbs_cert['serial_number']
                                         }),
                                     'key_encryption_algorithm': {
                                         'algorithm': u'rsa',
                                     },
                                     'encrypted_key':
                                     core.OctetString(encrypted_key)
                                 })
Ejemplo n.º 2
0
    def recipient_info(self, cert, session_key, oaep):
        public_key = cert.public_key()
        cert = signer.cert2asn(cert)

        tbs_cert = cert['tbs_certificate']
        # TODO: use subject_key_identifier when available
        if oaep:
            encrypted_key = public_key.encrypt(
                session_key,
                padding.OAEP(mgf=padding.MGF1(hashes.SHA512()),
                             algorithm=hashes.SHA512(),
                             label=None))
            kea = cms.KeyEncryptionAlgorithm({
                'algorithm':
                cms.KeyEncryptionAlgorithmId('rsaes_oaep'),
                'parameters':
                algos.RSAESOAEPParams({
                    'hash_algorithm':
                    algos.DigestAlgorithm({'algorithm': 'sha512'}),
                    'mask_gen_algorithm':
                    algos.MaskGenAlgorithm({
                        'algorithm':
                        algos.MaskGenAlgorithmId('mgf1'),
                        'parameters': {
                            'algorithm': algos.DigestAlgorithmId('sha512'),
                        }
                    }),
                    'p_source_algorithm':
                    algos.PSourceAlgorithm({
                        'algorithm':
                        algos.PSourceAlgorithmId('p_specified'),
                        'parameters':
                        b'',
                    })
                })
            })
        else:
            kea = {'algorithm': 'rsa'}
            encrypted_key = public_key.encrypt(session_key, padding.PKCS1v15())
        result = cms.RecipientInfo(name='ktri',
                                   value={
                                       'version':
                                       'v0',
                                       'rid':
                                       cms.RecipientIdentifier(
                                           name='issuer_and_serial_number',
                                           value={
                                               'issuer':
                                               tbs_cert['issuer'],
                                               'serial_number':
                                               tbs_cert['serial_number']
                                           }),
                                       'key_encryption_algorithm':
                                       kea,
                                       'encrypted_key':
                                       core.OctetString(encrypted_key)
                                   })
        return result
Ejemplo n.º 3
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),
     )
Ejemplo n.º 4
0
def return_ocsp_request_object(cert, issuer, algo, nonce=True):
    cert_details = ocsp.CertId({
        'issuer_name_hash':
        getattr(cert.issuer, algo),
        'issuer_key_hash':
        getattr(issuer.public_key, algo),
        'hash_algorithm':
        algos.DigestAlgorithm({'algorithm': algo}),
        'serial_number':
        cert.serial_number,
    })

    request_obj = ocsp.Request({
        'req_cert': cert_details,
    })

    tbs_request_obj = ocsp.TBSRequest(
        {'request_list': ocsp.Requests([request_obj])})

    if nonce:
        nonce_extension = ocsp.TBSRequestExtension({
            'extn_id':
            'nonce',
            'critical':
            True,
            'extn_value':
            core.OctetString(os.urandom(16)),
        })
        tbs_request_obj['request_extensions']: ocsp.TBSRequestExtensions(
            [nonce_extension])

    ocsp_request_obj = ocsp.OCSPRequest({
        'tbs_request': tbs_request_obj,
    })

    return ocsp_request_obj
Ejemplo n.º 5
0
    assert status.intact
    assert 'CONTENT_TIMESTAMP_TOKEN<INVALID>' in status.summary()
    assert 'TIMESTAMP_TOKEN<INTACT:UNTRUSTED>' in status.summary()


@freeze_time('2020-11-01')
@pytest.mark.parametrize('content,detach', [
    (b'This is not a TST!', True),
    (b'This is not a TST!', False),
    (cms.ContentInfo({
        'content_type': 'data', 'content': b'This is not a TST!'
    }), False),
    (cms.EncapsulatedContentInfo({
        'content_type': '2.999',
        'content': core.ParsableOctetString(
            core.OctetString(b'This is not a TST!').dump()
        )
    }), False),
    (cms.ContentInfo({'content_type': '2.999',}), True),
])
async def test_detached_with_malformed_content_tst(content, detach):
    class CustomProvider(CMSAttributeProvider):
        attribute_type = 'content_time_stamp'

        async def build_attr_value(self, dry_run=False):
            attr_value = await FROM_CA.async_sign_general_data(
                content, 'sha256',
                detached=detach,
            )
            return attr_value
Ejemplo n.º 6
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()
Ejemplo n.º 7
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()
Ejemplo n.º 8
0
def fetch(cert,
          issuer,
          hash_algo='sha1',
          nonce=True,
          user_agent=None,
          timeout=10):
    """
    Fetches an OCSP response for a certificate

    :param cert:
        An asn1cyrpto.x509.Certificate object to get an OCSP reponse for

    :param issuer:
        An asn1crypto.x509.Certificate object that is the issuer of cert

    :param hash_algo:
        A unicode string of "sha1" or "sha256"

    :param nonce:
        A boolean - if the nonce extension should be used to prevent replay
        attacks

    :param user_agent:
        The HTTP user agent to use when requesting the OCSP response. If None,
        a default is used in the format "certvalidation 1.0.0".

    :param timeout:
        The number of seconds after which an HTTP request should timeout

    :raises:
        urllib.error.URLError/urllib2.URLError - when a URL/HTTP error occurs
        socket.error - when a socket error occurs

    :return:
        An asn1crypto.ocsp.OCSPResponse object
    """

    if not isinstance(cert, x509.Certificate):
        raise TypeError(
            'cert must be an instance of asn1crypto.x509.Certificate, not %s' %
            type_name(cert))

    if not isinstance(issuer, x509.Certificate):
        raise TypeError(
            'issuer must be an instance of asn1crypto.x509.Certificate, not %s'
            % type_name(issuer))

    if hash_algo not in set(['sha1', 'sha256']):
        raise ValueError('hash_algo must be one of "sha1", "sha256", not %s' %
                         repr(hash_algo))

    if not isinstance(nonce, bool):
        raise TypeError('nonce must be a bool, not %s' % type_name(nonce))

    if user_agent is None:
        user_agent = 'certvalidator %s' % __version__
    elif not isinstance(user_agent, str_cls):
        raise TypeError('user_agent must be a unicode string, not %s' %
                        type_name(user_agent))

    cert_id = ocsp.CertId({
        'hash_algorithm':
        algos.DigestAlgorithm({'algorithm': hash_algo}),
        'issuer_name_hash':
        getattr(cert.issuer, hash_algo),
        'issuer_key_hash':
        getattr(issuer.public_key, hash_algo),
        'serial_number':
        cert.serial_number,
    })

    request = ocsp.Request({
        'req_cert': cert_id,
    })
    tbs_request = ocsp.TBSRequest({
        'request_list': ocsp.Requests([request]),
    })

    if nonce:
        nonce_extension = ocsp.TBSRequestExtension({
            'extn_id':
            'nonce',
            'critical':
            False,
            'extn_value':
            core.OctetString(core.OctetString(os.urandom(16)).dump())
        })
        tbs_request['request_extensions'] = ocsp.TBSRequestExtensions(
            [nonce_extension])

    ocsp_request = ocsp.OCSPRequest({
        'tbs_request': tbs_request,
    })

    last_e = None
    for ocsp_url in cert.ocsp_urls:
        try:
            request = Request(ocsp_url)
            request.add_header('Accept', 'application/ocsp-response')
            request.add_header('Content-Type', 'application/ocsp-request')
            request.add_header('User-Agent', user_agent)
            response = urlopen(request, ocsp_request.dump(), timeout)
            ocsp_response = ocsp.OCSPResponse.load(response.read())
            request_nonce = ocsp_request.nonce_value
            if ocsp_response['response_status'].native == 'unauthorized':
                raise errors.OCSPNoMatchesError(
                    'Unable to verify OCSP response since the responder returned unauthorized'
                )
            response_nonce = ocsp_response.nonce_value
            if request_nonce and response_nonce and request_nonce.native != response_nonce.native:
                raise errors.OCSPValidationError(
                    'Unable to verify OCSP response since the request and response nonces do not match'
                )
            return ocsp_response

        except (URLError) as e:
            last_e = e

    raise last_e