diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 6ecf6a05d5..a83d651022 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -25291,6 +25291,9 @@ typedef struct DerCert { #endif byte certPolicies[MAX_CERTPOL_NB*MAX_CERTPOL_SZ]; /* Certificate Policies */ byte crlInfo[CTC_MAX_CRLINFO_SZ]; /* CRL Distribution Points */ +#ifdef WOLFSSL_ACME_OID + byte acmeId[MAX_ACMEID_SZ]; /* RFC 8737 id-pe-acmeIdentifier */ +#endif #endif #ifdef WOLFSSL_CERT_REQ byte attrib[MAX_ATTRIB_SZ]; /* Cert req attributes encoded */ @@ -25321,6 +25324,9 @@ typedef struct DerCert { #endif int certPoliciesSz; /* encoded CertPolicies extension length*/ int crlInfoSz; /* encoded CRL Dist Points length */ +#ifdef WOLFSSL_ACME_OID + int acmeIdSz; /* encoded acmeIdentifier length */ +#endif #endif #ifdef WOLFSSL_ALT_NAMES int altNamesSz; /* encoded AltNames extension length */ diff --git a/wolfcrypt/src/asn_orig.c b/wolfcrypt/src/asn_orig.c index d6568aa5d1..b39417c60e 100644 --- a/wolfcrypt/src/asn_orig.c +++ b/wolfcrypt/src/asn_orig.c @@ -5295,6 +5295,31 @@ static int SetAKID(byte* output, word32 outSz, byte *input, word32 length, return (int)idx + enc_valSz; } +#ifdef WOLFSSL_ACME_OID +/* encode RFC 8737 id-pe-acmeIdentifier extension, return total bytes written + * RFC8737 : critical */ +static int SetAcmeIdentifier(byte* output, word32 outSz, const byte* digest, + word32 digestSz) +{ + byte inner[1 + MAX_LENGTH_SZ + WC_SHA256_DIGEST_SIZE]; + word32 innerSz; + const byte acmeId_oid[] = { 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x01, 0x1F, 0x01, 0x01, 0xFF, 0x04 }; + + if (output == NULL || digest == NULL) + return BAD_FUNC_ARG; + if (digestSz != WC_SHA256_DIGEST_SIZE) + return BAD_FUNC_ARG; + + innerSz = SetOctetString(digestSz, inner); + XMEMCPY(inner + innerSz, digest, digestSz); + innerSz += digestSz; + + return SetOidValue(output, outSz, acmeId_oid, sizeof(acmeId_oid), + inner, innerSz); +} +#endif /* WOLFSSL_ACME_OID */ + /* encode Key Usage, return total bytes written * RFC5280 : critical */ static int SetKeyUsage(byte* output, word32 outSz, word16 input) @@ -6340,6 +6365,22 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, der->certPoliciesSz = 0; #endif /* WOLFSSL_CERT_EXT */ +#ifdef WOLFSSL_ACME_OID + /* RFC 8737 id-pe-acmeIdentifier (TLS-ALPN-01 challenge cert). + * Always critical=TRUE. */ + if (cert->acmeIdentifierSz == WC_SHA256_DIGEST_SIZE) { + der->acmeIdSz = SetAcmeIdentifier(der->acmeId, sizeof(der->acmeId), + cert->acmeIdentifier, + (word32)cert->acmeIdentifierSz); + if (der->acmeIdSz <= 0) + return EXTENSIONS_E; + + der->extensionsSz += der->acmeIdSz; + } + else + der->acmeIdSz = 0; +#endif + /* put extensions */ if (der->extensionsSz > 0) { @@ -6436,6 +6477,17 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, return EXTENSIONS_E; } #endif /* WOLFSSL_CERT_EXT */ + +#ifdef WOLFSSL_ACME_OID + /* put ACME Identifier */ + if (der->acmeIdSz) { + ret = SetExtensions(der->extensions, sizeof(der->extensions), + &der->extensionsSz, + der->acmeId, der->acmeIdSz); + if (ret <= 0) + return EXTENSIONS_E; + } +#endif } der->total = der->versionSz + der->serialSz + der->sigAlgoSz + diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index d4ede74abd..abdfa953f9 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1310,6 +1310,10 @@ enum Misc_ASN { #endif MAX_CERTPOL_NB = CTC_MAX_CERTPOL_NB,/* Max number of Cert Policy */ MAX_CERTPOL_SZ = CTC_MAX_CERTPOL_SZ, +#endif +#ifdef WOLFSSL_ACME_OID + MAX_ACMEID_SZ = 19 + WC_SHA256_DIGEST_SIZE, /* Max encoded + acmeIdentifier size */ #endif OCSP_NONCE_EXT_SZ = 35, /* OCSP Nonce Extension size */ MAX_OCSP_EXT_SZ = 58, /* Max OCSP Extension length */