Skip to content

Latest commit

 

History

History
47 lines (37 loc) · 2.14 KB

certificates.md

File metadata and controls

47 lines (37 loc) · 2.14 KB

Certificates

Modifying and creating X.509 certificates is more involved than modifying a normal DER structure if one wishes to keep the signature valid. This document provides instructions for fixing up a modified test certificate's signature if the issuer's private key is available. (For a non-test certificate, this is the CA's private key and is presumably unavailable.)

X.509 certificates are specified in RFC 5280. The basic top-level structure is:

Certificate  ::=  SEQUENCE  {
     tbsCertificate       TBSCertificate,
     signatureAlgorithm   AlgorithmIdentifier,
     signatureValue       BIT STRING  }

The tbsCertificate is a large structure with the contents of the certificate. This includes the subject, issuer, public key, etc. The signatureAlgorithm specifies the signature algorithm and parameters. Finally, the signatureValue is the signature itself, created from the issuer's private key. This is the field that must be fixed once the tbsCertificate is modified.

The signature is computed over the serialized tbsCertificate, so, using a text editor, copy the tbsCertificate value into its own file, tbs-cert.txt. Now sign that with the issuing private key. If using OpenSSL's command-line tool, here is a sample command:

ascii2der -i tbs-cert.txt | openssl dgst -sha256 -sign issuer_key.pem | \
    xxd -p -c 9999 > signature.txt

For other options, replace -sha256 with a different digest or pass -sigopt. See OpenSSL's documentation for details. Note that, for a valid certificate, the signature parameters should match the signatureAlgorithm field. If using different signing parameters, update it and the copy in the tbsCertificate.

Finally, in a text editor, replace the signature with the new one. X.509 defines certificates as BIT STRINGs, but every signature algorithm uses byte strings, so include a leading zero to specify that no bits should be removed from the end:

BIT_STRING {
  `00` # No unused bits.
  `INSERT SIGNATURE HERE`
}

Finally, use ascii2der to convert the certificate to DER.