diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 6bcb5768c..689896a63 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -14478,54 +14478,66 @@ int wc_ParseCertPIV(wc_CertPIV* piv, const byte* buf, word32 totalSz) XMEMSET(piv, 0, sizeof(wc_CertPIV)); - /* Certificate - Total Length (0A 82 05FA) */ + /* Detect Identiv PIV (with 0x0A, 0x0B and 0x0C sections) */ + /* Certificate (0A 82 05FA) */ if (GetASNHeader(buf, ASN_PIV_CERT, &idx, &length, totalSz) >= 0) { - /* Certificate Buffer (53 82 05F6) */ - if (GetASNHeader(buf, ASN_APPLICATION | ASN_PRINTABLE_STRING, &idx, - &length, totalSz) < 0) { - return ASN_PARSE_E; - } - /* PIV Certificate (70 82 05ED) */ - if (GetASNHeader(buf, ASN_PIV_TAG_CERT, &idx, &length, - totalSz) < 0) { - return ASN_PARSE_E; - } + /* Identiv Type PIV card */ + piv->isIdentiv = 1; - /* Capture certificate buffer pointer and length */ piv->cert = &buf[idx]; piv->certSz = length; idx += length; - /* PIV Certificate Info (71 01 00) */ - if (GetASNHeader(buf, ASN_PIV_TAG_CERT_INFO, &idx, &length, - totalSz) >= 0) { - if (length >= 1) { - piv->compression = (buf[idx] & ASN_PIV_CERT_INFO_COMPRESSED); - piv->isX509 = (buf[idx] & ASN_PIV_CERT_INFO_ISX509); - } + /* Nonce (0B 14) */ + if (GetASNHeader(buf, ASN_PIV_NONCE, &idx, &length, totalSz) >= 0) { + piv->nonce = &buf[idx]; + piv->nonceSz = length; idx += length; } - /* PIV Error Detection (FE 00) */ - if (GetASNHeader(buf, ASN_PIV_TAG_ERR_DET, &idx, &length, - totalSz) >= 0) { - piv->certErrDet = &buf[idx]; - piv->certErrDetSz = length; + /* Signed Nonce (0C 82 0100) */ + if (GetASNHeader(buf, ASN_PIV_SIGNED_NONCE, &idx, &length, totalSz) >= 0) { + piv->signedNonce = &buf[idx]; + piv->signedNonceSz = length; idx += length; } + + idx = 0; + buf = piv->cert; + totalSz = piv->certSz; } - /* Nonce (0B 14) */ - if (GetASNHeader(buf, ASN_PIV_NONCE, &idx, &length, totalSz) >= 0) { - piv->nonce = &buf[idx]; - piv->nonceSz = length; + /* Certificate Buffer Total Size (53 82 05F6) */ + if (GetASNHeader(buf, ASN_APPLICATION | ASN_PRINTABLE_STRING, &idx, + &length, totalSz) < 0) { + return ASN_PARSE_E; + } + /* PIV Certificate (70 82 05ED) */ + if (GetASNHeader(buf, ASN_PIV_TAG_CERT, &idx, &length, + totalSz) < 0) { + return ASN_PARSE_E; + } + + /* Capture certificate buffer pointer and length */ + piv->cert = &buf[idx]; + piv->certSz = length; + idx += length; + + /* PIV Certificate Info (71 01 00) */ + if (GetASNHeader(buf, ASN_PIV_TAG_CERT_INFO, &idx, &length, + totalSz) >= 0) { + if (length >= 1) { + piv->compression = (buf[idx] & ASN_PIV_CERT_INFO_COMPRESSED); + piv->isX509 = (buf[idx] & ASN_PIV_CERT_INFO_ISX509); + } idx += length; } - /* Signed Nonce (0C 82 0100) */ - if (GetASNHeader(buf, ASN_PIV_SIGNED_NONCE, &idx, &length, totalSz) >= 0) { - piv->signedNonce = &buf[idx]; - piv->signedNonceSz = length; + /* PIV Error Detection (FE 00) */ + if (GetASNHeader(buf, ASN_PIV_TAG_ERR_DET, &idx, &length, + totalSz) >= 0) { + piv->certErrDet = &buf[idx]; + piv->certErrDetSz = length; idx += length; } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 2f4cefeb0..98b033dfd 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -20331,12 +20331,24 @@ int cryptodev_test(void) #ifdef WOLFSSL_CERT_PIV int certpiv_test(void) { - /* TODO: Add test for wc_ParseCertPIV */ -#if 0 + int ret; wc_CertPIV piv; - ret = wc_ParseCertPIV(&piv, buf, totalSz); -#endif - return 0; + + /* Template for Identiv PIV cert, nonce and signature */ + const byte pivCert[] = { + 0x0A, 0x0D, + 0x53, 0x04, /* NIST PIV Cert */ + 0x70, 0x02, /* Certificate */ + 0x30, 0x00, + 0x71, 0x01, 0x00, /* Cert Info */ + 0xFE, 0x00, /* Error Detection */ + 0x0B, 0x01, 0x00, /* Nonce */ + 0x0C, 0x01, 0x00, /* Signed Nonce */ + }; + + ret = wc_ParseCertPIV(&piv, pivCert, sizeof(pivCert)); + + return ret; } #endif /* WOLFSSL_CERT_PIV */ diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 9c5a1cf09..066336367 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -486,14 +486,15 @@ typedef struct _wc_CertPIV { word32 certSz; const byte* certErrDet; word32 certErrDetSz; - const byte* nonce; - word32 nonceSz; - const byte* signedNonce; - word32 signedNonceSz; + const byte* nonce; /* Identiv Only */ + word32 nonceSz; /* Identiv Only */ + const byte* signedNonce; /* Identiv Only */ + word32 signedNonceSz; /* Identiv Only */ /* flags */ word16 compression:2; word16 isX509:1; + word16 isIdentiv:1; } wc_CertPIV; WOLFSSL_API int wc_ParseCertPIV(wc_CertPIV* cert, const byte* buf, word32 totalSz);