I am working on a Let's Encrypt client that needs to create a new CSR,
signed with a new key, every time that it renews a certificate.  AFAICT,
there really isn't any sort of "CSR template" format that I could put in
a configuration file, so my preferred approach would be to simply use an
existing CSR to store the name, attributes, and extensions, and then
"re-sign" it with the new key.

Of course, it isn't actually possible to re-sign an existing CSR, so I
need to create a CSRBuilder, copy the name, attributes, and extensions
from the old CSR to the CSRBuilder, and create a new CSR that is signed
with my new key.

The subject name and extensions are straightforward.

  csrb = x509.CertificateSigningRequestBuilder()
  csrb = csrb.subject_name(csr.subject)
  for ext in csr.extensions:
      csrb = csrb.add_extension(ext.value, ext.critical)

Attributes are a bit more complicated for a couple of reasons.

First, the extension request (OID 1.2.840.113549.1.9.14) also shows up
as an attribute.  It's simple to skip this particular OID when copying
the attributes.

The second issue is that CSRBuilder.add_attribute() defaults to not
setting the "tag" of attributes that it adds, which causes
CSRBuilder.sign() to check that the attribute values are valid UTF-8
(and raise an exception for any attribute whose value isn't UTF-8).
I am working around this by using the (undocumented) _tag parameter to
explicitly set it.

  CRMF_EXT_REQ_OID = x509.ObjectIdentifier('1.2.840.113549.1.9.14')
  for attr in csr.attributes:
      if attr.oid == CRMF_EXT_REQ_OID:
          continue
      try:
          atype = x509.name._ASN1Type(attr._type)
      except ValueError:
          print(f'Unsupported attribute type: '
                f'oid={attr.oid}, type={attr._type}')
          continue
      csrb = csrb.add_attribute(attr.oid, attr.value, _tag=atype)

Does this seem reasonable?  Am I missing anything?

Thanks!

--
========================================================================
If your user interface is intuitive in retrospect ... it isn't intuitive
========================================================================

_______________________________________________
Cryptography-dev mailing list
Cryptography-dev@python.org
https://mail.python.org/mailman/listinfo/cryptography-dev

Reply via email to