Certificate request messages

The RFC 4211 certificate-request-message producing side. pki.crmf.build assembles a CertReqMessages -- one or more CertReqMsg, each a CertRequest (a CertTemplate of the requested certificate fields plus optional controls) paired with a proof of possession. The common proof is a POPOSigningKey signature over the CertRequest, made with the private half of the key being certified (the requester proves possession, exactly as a PKCS#10 CSR does). The message drops into a CMP (RFC 9810) or EST enrollment body. Parsing lives at pki.schema.crmf.parse.

pki.crmf.build

since 0.3.3 experimental
pki.crmf.build(spec, key?, opts?) -> Promise<Buffer|string>

Build and DER-encode an RFC 4211 CertReqMessages. spec describes one certificate request message (or pass spec.messages -- an array of specs -- for a batch): certReqId (an integer, default 0; the RFC 9483 -1 sentinel is allowed), certTemplate (the requested certificate fields -- subject, publicKey (the SPKI DER of the key being certified), validity ({ notBefore, notAfter } Dates), extensions (an object of subjectAltName / keyUsage / extendedKeyUsage / basicConstraints / certificatePolicies / subjectKeyIdentifier, or pre-encoded Extension DER), and an optional version (2)), optional controls and regInfo (an object of regToken / authenticator / utf8Pairs / oldCertID / protocolEncrKey, or pre-encoded AttributeTypeAndValue DER), and an optional pop selector. key (or { key }) is the REQUESTER's private key -- the private half of certTemplate.publicKey; the message carries a POPOSigningKey proof of possession signed with it (verified before the message is returned), exactly as a PKCS#10 CSR proves possession. The signature algorithm is resolved from the requested public key (RSA PKCS#1 v1.5 / PSS, ECDSA, EdDSA, ML-DSA, SLH-DSA, or a composite arm). key is optional -- omit it for a raVerified proof (opt in with pop: { type: 'raVerified', raVerified: true }). Returns DER, or a PEM block with opts.pem (the label is required). Malformed input throws a typed CrmfError. Certificate-request-message parsing is pki.schema.crmf.parse.

Options

- `pem` (string) -- return a PEM block with this label instead of DER (e.g. "CERTIFICATE REQUEST MESSAGE").
- `pss` (boolean) -- sign an RSA key with RSASSA-PSS rather than PKCS#1 v1.5.
- `digestAlgorithm` (string) -- override the message digest where the algorithm permits a choice.

Example

async function example() {
  var msg = await pki.crmf.build(
    { certReqId: 0, certTemplate: { subject: "device-42", publicKey: signerSpki } },
    { key: signerKeyPkcs8 });
  pki.schema.crmf.parse(msg).messages[0].certReq.certTemplate.subject.dn;   // "CN=device-42"
}
example();

References

  • spec RFC 4211
  • defends forged-certificate-request (CWE-347)

pki.crmf.buildCertTemplate

since 0.3.5 experimental
pki.crmf.buildCertTemplate(template) -> Buffer

Encode a bare RFC 4211 CertTemplate (the requested-certificate fields -- subject, publicKey, validity, requested extensions, an optional version 2, issuer) to canonical DER. This is the certTemplate interior of pki.crmf.build, exposed for the RFC 9810 CMP rr (revocation request) body, whose RevDetails.certDetails carries a CertTemplate naming the certificate to revoke. Returns the DER Buffer; a malformed template throws a typed CrmfError.

Example

var tpl = pki.crmf.buildCertTemplate({ serialNumber: 42n, issuer: "CN=CA" });
pki.asn1.decode(tpl).tagNumber === pki.asn1.TAGS.SEQUENCE;   // the CertTemplate SEQUENCE

References