question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot extract pubkey from certificate

See original GitHub issue

I have this code below working, but:

  1. I’m unable to read pubkey from the generated certificate. AFAIK, a certificate is composed by some elements, including signature algorithm, public key and the signature itself, so anyone could verify the signature using same algorithm and the pubkey, right? I tried
openssl x509 -pubkey -noout -in cert.pem 
Error getting public key
140003854860736:error:0D0680A8:asn1 encoding routines:asn1_check_tlen:wrong tag:../crypto/asn1/tasn_dec.c:1129:
140003854860736:error:0D06C03A:asn1 encoding routines:asn1_d2i_ex_primitive:nested asn1 error:../crypto/asn1/tasn_dec.c:693:
140003854860736:error:0D08303A:asn1 encoding routines:asn1_template_noexp_d2i:nested asn1 error:../crypto/asn1/tasn_dec.c:626:Field=n, Type=RSA
140003854860736:error:0408B004:rsa routines:rsa_pub_decode:RSA lib:../crypto/rsa/rsa_ameth.c:51:
140003854860736:error:0B09407D:x509 certificate routines:x509_pubkey_decode:public key decode error:../crypto/x509/x_pubkey.c:124:

Code:

            try:
                for token in lib.get_tokens():
                    if token.serial.decode() == TOKEN_SERIAL:
                        with token.open(user_pin=PIN) as session:
                            priv = ''
                            pub = ''
                            try:
                                # priv = session.get_key(object_class=pkcs11.constants.ObjectClass.PRIVATE_KEY, label=TOKEN_LABEL)
                                priv = session.get_key(object_class=pkcs11.constants.ObjectClass.PRIVATE_KEY)
                            except pkcs11.exceptions.NoSuchKey:
                                for j in session.get_objects({Attribute.CLASS: ObjectClass.PRIVATE_KEY}):
                                    priv = j
                                    break
                            except pkcs11.exceptions.MultipleObjectsReturned:
                                for j in session.get_objects({Attribute.CLASS: ObjectClass.PRIVATE_KEY}):
                                    priv = j
                                    break

                            certificate = next(session.get_objects({Attribute.CLASS: pkcs11.constants.ObjectClass.CERTIFICATE}))
                            der_bytes = certificate[Attribute.VALUE]
                            pem_bytes = pem.armor('CERTIFICATE', der_bytes)
                            token_certificate = pem_bytes.decode()

                            try:
                                # pub = session.get_key(object_class=pkcs11.constants.ObjectClass.PUBLIC_KEY, label=TOKEN_LABEL)
                                pub = encode_rsa_public_key(session.get_key(object_class=pkcs11.constants.ObjectClass.PUBLIC_KEY))

                            except pkcs11.MultipleObjectsReturned:
                                for i in session.get_objects({Attribute.CLASS: pkcs11.constants.ObjectClass.PUBLIC_KEY}):
                                    pub = encode_rsa_public_key(i)
                                    break

                            except pkcs11.exceptions.NoSuchKey:
                                cert2 = x509.load_pem_x509_certificate(pem.armor('CERTIFICATE', der_bytes),default_backend())
                                # pubdata = cert2.public_key().public_bytes(cryptography.hazmat.primitives.serialization.Encoding.DER,cryptography.hazmat.primitives.serialization.PublicFormat.SubjectPublicKeyInfo)
                                pubdata = cert2.public_key().public_bytes(cryptography.hazmat.primitives.serialization.Encoding.DER,cryptography.hazmat.primitives.serialization.PublicFormat.SubjectPublicKeyInfo)
                                # pub = pem.armor('RSA PUBLIC KEY', pubdata)
                                pub = pubdata

                            NASC_CPF_MATRICULA_RG_SIGLAEXPEDIDOR_UF = NASCIMENTO + CPF + MATRICULA + RG + SIGLAEXPEDIDOR_E_UF
                            INSTENSINO_GRAUESCOLARIDADE_NOMECURSO_MUNICINSTIT_UF = str(INSTENSINO) + str(ESCOLARIDADE) + str(NOME_CURSO) + str(MUNICIPIO_INSTENSINO) + str(UF_INSTENSINO)

                            extension1 = Extension({'extn_id': ExtensionId('2.16.76.1.10.1'),
                                                    'critical': False,
                                                    'extn_value': NASC_CPF_MATRICULA_RG_SIGLAEXPEDIDOR_UF.encode()
                                                    })
                            extension2 = Extension({'extn_id': ExtensionId('2.16.76.1.10.2'),
                                                    'critical': False,
                                                    'extn_value': unidecode.unidecode(
                                                        INSTENSINO_GRAUESCOLARIDADE_NOMECURSO_MUNICINSTIT_UF).encode()
                                                    })

                            extension3 = False

                            if NOME_SOCIAL is not False or NOME_SOCIAL != "False":
                                extension3 = Extension({'extn_id': ExtensionId('2.16.76.1.4.3'),
                                                        'critical': False,
                                                        'extn_value': unidecode.unidecode(
                                                            NOME_SOCIAL).encode()
                                                        })


                            authority_key_identifier = Extension({
                                'extn_id': ExtensionId('authority_key_identifier'),
                                'critical': False,
                                'extn_value': AuthorityKeyIdentifier({
                                  'key_identifier': AUTHORITY_KEY_IDENTIFIER.encode()
                                    })
                            })

                            authority_information_access = Extension({
                                'extn_id': ExtensionId('authority_information_access'),
                                'critical': False,
                                'extn_value': [{
                                    'access_method': AccessMethod('1.3.6.1.5.5.7.48.5'),
                                    'access_location': GeneralName('uniform_resource_identifier', URI(AUTHORITY_INFORMATION_ACCESS))
                                }]
                            })
                            crl_distribution_point = Extension({
                                'extn_id': ExtensionId('crl_distribution_points'),
                                'critical': False,
                                'extn_value': [{
                                    'distribution_point': DistributionPointName('full_name', [GeneralName('uniform_resource_identifier', URI(CRL_DISTRIBUTION_POINT))]),
                                    # 'crl_issuer': [GeneralName('uniform_resource_identifier', URI(CRL_DISTRIBUTION_POINT))]
                                }]
                            })

                            # sha256_rsa
                            signed_digest_algo = 'sha256_rsa'


                            if extension3:
                                extensions_tuple = (extension1, extension2, extension3, authority_information_access, crl_distribution_point, authority_key_identifier)
                            else:
                                extensions_tuple = (extension1, extension2, authority_information_access, crl_distribution_point, authority_key_identifier)


                            tbs = TbsCertificate({
                                'version': Version(1),
                                'serial_number': int(SERIAL),
                                'issuer': Name.build({
                                    'common_name': EEA_COMMON_NAME,
                                }),
                                'subject': Name.build({
                                    'common_name': COMMON_NAME,
                                }),
                                'signature': {
                                    'algorithm': signed_digest_algo,
                                    'parameters': None,
                                },
                                'extensions': (extensions_tuple),

                                'validity': {
                                    'not_before': Time({
                                        'general_time': GeneralizedTime(parser.parse(NOT_VALID_BEFORE)),
                                    }),
                                    'not_after': Time({
                                        'general_time': GeneralizedTime(parser.parse(NOT_VALID_AFTER)),
                                    }),
                                },
                                'subject_public_key_info': {
                                    'algorithm': {
                                        'algorithm': 'rsa',
                                        'parameters': None,
                                    },
                                    # 'public_key': RSAPublicKey.load(encode_rsa_public_key(pub)),
                                    'public_key': RSAPublicKey.load(pub),
                                }
                            })

                            # Sign the TBS Certificate
                            value = priv.sign(tbs.dump(),
                                              mechanism=Mechanism.SHA256_RSA_PKCS)

                            cert = Certificate({
                                'tbs_certificate': tbs,
                                'signature_algorithm': {
                                    'algorithm': signed_digest_algo,
                                    'parameters': None,
                                },
                                'signature_value': value,
                            })
                            attribute_certificate = pem.armor('CERTIFICATE', cert.dump()).decode()
                            return (attribute_certificate + token_certificate).strip()
                    else:
                        return 'Token not found'
            except TokenNotPresent:
                pass

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:14

github_iconTop GitHub Comments

1reaction
ftbaratacommented, Jan 24, 2019

Hi again @joernheissler ! If you are in doubt about what pub is,

pub = encode_rsa_public_key(session.get_key(object_class=pkcs11.constants.ObjectClass.PUBLIC_KEY))

So, pub is the Public Key extracted from the USB token, right?

And, considering your suggestion, I am in doubt if you mean to do:

 },
                                'subject_public_key_info': {
                                    'algorithm': {
                                        'algorithm': 'rsa',
                                        'parameters': None,
                                    },
                                     'public_key': PublicKeyInfo.load(pub),
                                }

Or

 },
                               'subject_public_key_info': PublicKeyInfo.load(pub)
                                }

In both cases, the variable PublicKeyInfo does not exist. Besides, the second example I gave may be incorrect for asn1crypto syntax stuff. Do you known the asn1crypto properly usage?

0reactions
ftbaratacommented, Feb 16, 2019

Sorry, I made I mistake. I was passing public key instead of public key info.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to save public key from a certificate in .pem format
Problem #1 - the certificate is written with the public key. I am using the below openssl command for storing my public key...
Read more >
Extract RSA Public Key from public Certificate - Super User
I have public certificate with 2048 bit RSA public key for encrypt data. I need use openssl to extract this public key.
Read more >
How to extract the SSH public key from a Login certificate
This article will show how to extract the SSH key from the available certificate (located on the Login Certificates tab under the original ......
Read more >
How to Extract the Private and Public Key From pfx File
Note: First you will need a linux based operating system that supports openssl command to run the following commands. Extract the key-pair
Read more >
PFX Certificate Export | Certificate Utility - DigiCert.com
Background. Windows servers use .pfx files that contain the public key file (SSL certificate file) and the associated private key file. DigiCert provides...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found