mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-01-26 16:16:31 -06:00
pkcs10: remove pyasn1 PKCS #10 spec
In the dogtag-ipa-ca-renew-agent-submit certmonger renewal helper, we currently use our hand-rolled PKCS #10 pyasn1 specification to parse the friendlyName out of CSRs generated by certmonger (it contains the NSSDB nickname of the cert). Use other information from the renewal helper process environment to determine the nickname and remove our PKCS #10 pyasn1 spec. Part of: https://fedorahosted.org/freeipa/ticket/6398 Reviewed-By: Jan Cholasta <jcholast@redhat.com> Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
This commit is contained in:
parent
66637f766d
commit
85487281cd
@ -39,10 +39,10 @@ import six
|
||||
|
||||
from ipapython import ipautil
|
||||
from ipapython.dn import DN
|
||||
from ipalib import api, errors, pkcs10, x509
|
||||
from ipalib import api, errors, x509
|
||||
from ipaplatform.paths import paths
|
||||
from ipaserver.plugins.ldap2 import ldap2
|
||||
from ipaserver.install import cainstance, certs
|
||||
from ipaserver.install import cainstance, dsinstance, certs
|
||||
|
||||
# This is a certmonger CA helper script for IPA CA subsystem cert renewal. See
|
||||
# https://git.fedorahosted.org/cgit/certmonger.git/tree/doc/submit.txt for more
|
||||
@ -65,8 +65,36 @@ if six.PY3:
|
||||
IPA_CA_NICKNAME = 'caSigningCert cert-pki-ca'
|
||||
|
||||
def get_nickname():
|
||||
csr = os.environ.get('CERTMONGER_CSR')
|
||||
return pkcs10.get_friendlyname(csr) if csr else None
|
||||
subject = os.environ.get('CERTMONGER_REQ_SUBJECT')
|
||||
if not subject:
|
||||
return None
|
||||
|
||||
subject_base = dsinstance.DsInstance().find_subject_base()
|
||||
if not subject_base:
|
||||
return None
|
||||
|
||||
nickname_by_subject_dn = {
|
||||
DN('CN=Certificate Authority', subject_base):
|
||||
'caSigningCert cert-pki-ca',
|
||||
DN('CN=CA Audit', subject_base): 'auditSigningCert cert-pki-ca',
|
||||
DN('CN=OCSP Subsystem', subject_base): 'ocspSigningCert cert-pki-ca',
|
||||
DN('CN=CA Subsystem', subject_base): 'subsystemCert cert-pki-ca',
|
||||
DN('CN=KRA Audit', subject_base): 'auditSigningCert cert-pki-kra',
|
||||
DN('CN=KRA Transport Certificate', subject_base):
|
||||
'transportCert cert-pki-kra',
|
||||
DN('CN=KRA Storage Certificate', subject_base):
|
||||
'storageCert cert-pki-kra',
|
||||
DN('CN=IPA RA', subject_base): 'ipaCert',
|
||||
}
|
||||
|
||||
try:
|
||||
return nickname_by_subject_dn[DN(subject)]
|
||||
except KeyError:
|
||||
cas = api.Command.ca_find(ipacasubjectdn=DN(subject))['result']
|
||||
if len(cas) == 0:
|
||||
return None
|
||||
return 'caSigningCert cert-pki-ca {}'.format(cas[0]['ipacaid'][0])
|
||||
|
||||
|
||||
def is_lightweight_ca():
|
||||
nickname = get_nickname() or ''
|
||||
@ -216,13 +244,9 @@ def store_cert():
|
||||
else:
|
||||
return (OPERATION_NOT_SUPPORTED_BY_HELPER,)
|
||||
|
||||
csr = os.environ.get('CERTMONGER_CSR')
|
||||
if not csr:
|
||||
return (UNCONFIGURED, "Certificate request not provided")
|
||||
|
||||
nickname = pkcs10.get_friendlyname(csr)
|
||||
nickname = get_nickname()
|
||||
if not nickname:
|
||||
return (REJECTED, "No friendly name in the certificate request")
|
||||
return (REJECTED, "Nickname could not be determined")
|
||||
|
||||
cert = os.environ.get('CERTMONGER_CERTIFICATE')
|
||||
if not cert:
|
||||
@ -325,13 +349,9 @@ def retrieve_or_reuse_cert():
|
||||
Retrieve certificate from LDAP. If the certificate is not available, reuse
|
||||
the old certificate.
|
||||
"""
|
||||
csr = os.environ.get('CERTMONGER_CSR')
|
||||
if not csr:
|
||||
return (UNCONFIGURED, "Certificate request not provided")
|
||||
|
||||
nickname = pkcs10.get_friendlyname(csr)
|
||||
nickname = get_nickname()
|
||||
if not nickname:
|
||||
return (REJECTED, "No friendly name in the certificate request")
|
||||
return (REJECTED, "Nickname could not be determined")
|
||||
|
||||
cert = os.environ.get('CERTMONGER_CERTIFICATE')
|
||||
if not cert:
|
||||
|
@ -23,57 +23,8 @@ import binascii
|
||||
import sys
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
import cryptography.x509
|
||||
from pyasn1.type import univ, namedtype, tag
|
||||
from pyasn1.codec.der import decoder
|
||||
|
||||
|
||||
# Unfortunately, NSS can only parse the extension request attribute, so
|
||||
# we have to parse friendly name ourselves (see RFC 2986)
|
||||
class _Attribute(univ.Sequence):
|
||||
componentType = namedtype.NamedTypes(
|
||||
namedtype.NamedType('type', univ.ObjectIdentifier()),
|
||||
namedtype.NamedType('values', univ.Set()),
|
||||
)
|
||||
|
||||
class _Attributes(univ.SetOf):
|
||||
componentType = _Attribute()
|
||||
|
||||
class _CertificationRequestInfo(univ.Sequence):
|
||||
componentType = namedtype.NamedTypes(
|
||||
namedtype.NamedType('version', univ.Integer()),
|
||||
namedtype.NamedType('subject', univ.Sequence()),
|
||||
namedtype.NamedType('subjectPublicKeyInfo', univ.Sequence()),
|
||||
namedtype.OptionalNamedType('attributes', _Attributes().subtype(
|
||||
implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)))
|
||||
)
|
||||
|
||||
class _CertificationRequest(univ.Sequence):
|
||||
componentType = namedtype.NamedTypes(
|
||||
namedtype.NamedType('certificationRequestInfo',
|
||||
_CertificationRequestInfo()),
|
||||
namedtype.NamedType('signatureAlgorithm', univ.Sequence()),
|
||||
namedtype.NamedType('signatureValue', univ.BitString()),
|
||||
)
|
||||
|
||||
_FRIENDLYNAME = univ.ObjectIdentifier('1.2.840.113549.1.9.20')
|
||||
|
||||
def get_friendlyname(csr, datatype=PEM):
|
||||
"""
|
||||
Given a CSR return the value of the friendlyname attribute, if any.
|
||||
|
||||
The return value is a string.
|
||||
"""
|
||||
if datatype == PEM:
|
||||
csr = strip_header(csr)
|
||||
csr = base64.b64decode(csr)
|
||||
|
||||
csr = decoder.decode(csr, asn1Spec=_CertificationRequest())[0]
|
||||
for attribute in csr['certificationRequestInfo']['attributes']:
|
||||
if attribute['type'] == _FRIENDLYNAME:
|
||||
return unicode(attribute['values'][0])
|
||||
|
||||
return None
|
||||
|
||||
def strip_header(csr):
|
||||
"""
|
||||
Remove the header and footer from a CSR.
|
||||
@ -113,4 +64,3 @@ if __name__ == '__main__':
|
||||
csr = ''.join(csrlines)
|
||||
|
||||
print(load_certificate_request(csr))
|
||||
print(get_friendlyname(csr))
|
||||
|
Loading…
Reference in New Issue
Block a user