Skip to content

Commit e1e06d6

Browse files
committed
Add cert/CRL capabilities: skid, akid, dist point, netscape
1 parent 8192c01 commit e1e06d6

13 files changed

Lines changed: 677 additions & 148 deletions

File tree

certs/crl/crlEccOut.der

-376 Bytes
Binary file not shown.

certs/crl/crlEccOut.pem

Lines changed: 0 additions & 10 deletions
This file was deleted.

certs/crl/crlRsaOut.der

-565 Bytes
Binary file not shown.

certs/crl/crlRsaOut.pem

Lines changed: 0 additions & 14 deletions
This file was deleted.

scripts/crl-gen-openssl.test

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ check_crl() {
9595
-CRLfile "$crl" \
9696
"$revoked_cert" 2>&1) || verify_rc=$?
9797
verify_rc=${verify_rc:-0}
98-
if ! echo "$verify_out" | grep -qi "revoked"; then
98+
# Avoid pipefail/SIGPIPE false negatives with `grep -q` in a pipeline.
99+
if ! grep -qi "revoked" <<< "$verify_out"; then
99100
echo "expected revoked verification failure for $label CRL"
100101
echo "$verify_out"
101102
return 1

src/crl.c

Lines changed: 125 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type,
825825
*/
826826
int BufferStoreCRL(WOLFSSL_CRL* crl, byte* buff, long* inOutSz, int type)
827827
{
828+
int ret = 0;
828829
CRL_Entry* ent = NULL;
829830
const byte* tbs = NULL;
830831
word32 tbsSz = 0;
@@ -850,7 +851,8 @@ int BufferStoreCRL(WOLFSSL_CRL* crl, byte* buff, long* inOutSz, int type)
850851

851852
outSz = *inOutSz;
852853

853-
/* Access the first CRL entry. */
854+
/* Access the first CRL entry. Lock is held until encoding is complete
855+
* to prevent the entry from being freed by another thread. */
854856
if (wc_LockRwLock_Rd(&crl->crlLock) != 0) {
855857
WOLFSSL_MSG("wc_LockRwLock_Rd failed");
856858
return BAD_MUTEX_E;
@@ -867,59 +869,63 @@ int BufferStoreCRL(WOLFSSL_CRL* crl, byte* buff, long* inOutSz, int type)
867869
sigParamsSz = ent->sigParamsSz;
868870
#endif
869871
}
870-
wc_UnLockRwLock(&crl->crlLock);
871872

872873
if (ent == NULL || tbs == NULL || tbsSz == 0 || sig == NULL || sigSz == 0) {
873874
WOLFSSL_MSG("CRL entry missing toBeSigned/signature data");
874-
return BAD_FUNC_ARG;
875+
ret = BAD_FUNC_ARG;
875876
}
876877

877878
/* Calculate encoded lengths for AlgorithmIdentifier. */
879+
if (ret == 0) {
878880
#ifdef WC_RSA_PSS
879-
if (sigParams != NULL && sigParamsSz > 0) {
880-
/* OID + explicit parameters inside SEQUENCE */
881-
word32 oidSz = 0;
882-
word32 idLen;
883-
const byte* oid = OidFromId(sigOID, oidSigType, &oidSz);
884-
if (oid == NULL) {
885-
WOLFSSL_MSG("Unknown signature OID for CRL");
886-
return WOLFSSL_FATAL_ERROR;
881+
if (sigParams != NULL && sigParamsSz > 0) {
882+
/* OID + explicit parameters inside SEQUENCE */
883+
word32 oidSz = 0;
884+
word32 idLen;
885+
const byte* oid = OidFromId(sigOID, oidSigType, &oidSz);
886+
if (oid == NULL) {
887+
WOLFSSL_MSG("Unknown signature OID for CRL");
888+
ret = WOLFSSL_FATAL_ERROR;
889+
}
890+
else {
891+
/* OBJECT IDENTIFIER header */
892+
idLen = (word32)SetObjectId((int)oidSz, NULL);
893+
algoLen = SetSequence(idLen + oidSz + sigParamsSz, NULL)
894+
+ idLen + oidSz + sigParamsSz;
895+
}
887896
}
888-
/* OBJECT IDENTIFIER header */
889-
idLen = (word32)SetObjectId((int)oidSz, NULL);
890-
algoLen = SetSequence(idLen + oidSz + sigParamsSz, NULL)
891-
+ idLen + oidSz + sigParamsSz;
892-
}
893-
else
897+
else
894898
#endif
895-
{
896-
algoLen = SetAlgoID((int)sigOID, NULL, oidSigType, 0);
897-
if (algoLen == 0) {
898-
WOLFSSL_MSG("SetAlgoID failed");
899-
return WOLFSSL_FATAL_ERROR;
899+
{
900+
algoLen = SetAlgoID((int)sigOID, NULL, oidSigType, 0);
901+
if (algoLen == 0) {
902+
WOLFSSL_MSG("SetAlgoID failed");
903+
ret = WOLFSSL_FATAL_ERROR;
904+
}
900905
}
901906
}
902907

903-
/* BIT STRING header for signature */
904-
bitHdrLen = SetBitString(sigSz, 0, NULL);
908+
if (ret == 0) {
909+
/* BIT STRING header for signature */
910+
bitHdrLen = SetBitString(sigSz, 0, NULL);
905911

906-
/* Compute total DER size. */
907-
totalContentLen = tbsSz + algoLen + bitHdrLen + sigSz;
908-
outerHdrLen = SetSequence(totalContentLen, NULL);
909-
derNeeded = outerHdrLen + totalContentLen;
912+
/* Compute total DER size. */
913+
totalContentLen = tbsSz + algoLen + bitHdrLen + sigSz;
914+
outerHdrLen = SetSequence(totalContentLen, NULL);
915+
derNeeded = outerHdrLen + totalContentLen;
916+
}
910917

911-
if (type == WOLFSSL_FILETYPE_ASN1) {
918+
if (ret == 0 && type == WOLFSSL_FILETYPE_ASN1) {
912919
if (buff == NULL) {
913920
*inOutSz = (long)derNeeded;
914-
return WOLFSSL_SUCCESS;
921+
ret = WOLFSSL_SUCCESS;
915922
}
916-
if ((long)derNeeded > outSz) {
923+
else if ((long)derNeeded > outSz) {
917924
WOLFSSL_MSG("Output buffer too small for DER CRL");
918-
return BUFFER_E;
925+
ret = BUFFER_E;
919926
}
920-
921-
/* Encode DER CRL directly into caller buffer. */
922-
{
927+
else {
928+
/* Encode DER CRL directly into caller buffer. */
923929
word32 pos = 0;
924930
#ifdef WC_RSA_PSS
925931
word32 oidSz = 0;
@@ -938,45 +944,50 @@ int BufferStoreCRL(WOLFSSL_CRL* crl, byte* buff, long* inOutSz, int type)
938944
oid = OidFromId(sigOID, oidSigType, &oidSz);
939945
if (oid == NULL) {
940946
WOLFSSL_MSG("Unknown signature OID for CRL");
941-
return WOLFSSL_FATAL_ERROR;
947+
ret = WOLFSSL_FATAL_ERROR;
948+
}
949+
else {
950+
/* SEQUENCE header for AlgorithmIdentifier */
951+
pos += SetSequence((word32)SetObjectId((int)oidSz, NULL) +
952+
oidSz + sigParamsSz, buff + pos);
953+
/* OBJECT IDENTIFIER header and content */
954+
pos += (word32)SetObjectId((int)oidSz, buff + pos);
955+
XMEMCPY(buff + pos, oid, oidSz);
956+
pos += oidSz;
957+
/* Parameters as captured (already DER encoded) */
958+
XMEMCPY(buff + pos, sigParams, sigParamsSz);
959+
pos += sigParamsSz;
942960
}
943-
/* SEQUENCE header for AlgorithmIdentifier */
944-
pos += SetSequence((word32)SetObjectId((int)oidSz, NULL) +
945-
oidSz + sigParamsSz, buff + pos);
946-
/* OBJECT IDENTIFIER header and content */
947-
pos += (word32)SetObjectId((int)oidSz, buff + pos);
948-
XMEMCPY(buff + pos, oid, oidSz);
949-
pos += oidSz;
950-
/* Parameters as captured (already DER encoded) */
951-
XMEMCPY(buff + pos, sigParams, sigParamsSz);
952-
pos += sigParamsSz;
953961
}
954962
else
955963
#endif
956964
{
957965
pos += SetAlgoID((int)sigOID, buff + pos, oidSigType, 0);
958966
}
959967

960-
/* signature BIT STRING and bytes */
961-
pos += SetBitString(sigSz, 0, buff + pos);
962-
XMEMCPY(buff + pos, sig, sigSz);
968+
if (ret == 0) {
969+
/* signature BIT STRING and bytes */
970+
pos += SetBitString(sigSz, 0, buff + pos);
971+
XMEMCPY(buff + pos, sig, sigSz);
972+
973+
*inOutSz = (long)derNeeded;
974+
ret = WOLFSSL_SUCCESS;
975+
}
963976
(void)pos; /* pos not used after this point */
964977
}
965-
966-
*inOutSz = (long)derNeeded;
967-
return WOLFSSL_SUCCESS;
968978
}
969979
#ifdef WOLFSSL_DER_TO_PEM
970-
else if (type == WOLFSSL_FILETYPE_PEM) {
980+
else if (ret == 0 && type == WOLFSSL_FILETYPE_PEM) {
971981
byte* derTmp = NULL;
972982
int pemSz;
973983
/* Build DER first in a temporary buffer. */
974984
derTmp = (byte*)XMALLOC(derNeeded, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
975985
if (derTmp == NULL) {
976-
return MEMORY_E;
986+
ret = MEMORY_E;
977987
}
978-
/* Encode DER CRL into temporary buffer. */
979-
{
988+
989+
if (ret == 0) {
990+
/* Encode DER CRL into temporary buffer. */
980991
word32 pos = 0;
981992
#ifdef WC_RSA_PSS
982993
word32 oidSz = 0;
@@ -989,56 +1000,63 @@ int BufferStoreCRL(WOLFSSL_CRL* crl, byte* buff, long* inOutSz, int type)
9891000
if (sigParams != NULL && sigParamsSz > 0) {
9901001
oid = OidFromId(sigOID, oidSigType, &oidSz);
9911002
if (oid == NULL) {
992-
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
993-
return WOLFSSL_FATAL_ERROR;
1003+
ret = WOLFSSL_FATAL_ERROR;
1004+
}
1005+
else {
1006+
pos += SetSequence((word32)SetObjectId((int)oidSz, NULL) +
1007+
oidSz + sigParamsSz, derTmp + pos);
1008+
pos += (word32)SetObjectId((int)oidSz, derTmp + pos);
1009+
XMEMCPY(derTmp + pos, oid, oidSz);
1010+
pos += oidSz;
1011+
XMEMCPY(derTmp + pos, sigParams, sigParamsSz);
1012+
pos += sigParamsSz;
9941013
}
995-
pos += SetSequence((word32)SetObjectId((int)oidSz, NULL) +
996-
oidSz + sigParamsSz, derTmp + pos);
997-
pos += (word32)SetObjectId((int)oidSz, derTmp + pos);
998-
XMEMCPY(derTmp + pos, oid, oidSz);
999-
pos += oidSz;
1000-
XMEMCPY(derTmp + pos, sigParams, sigParamsSz);
1001-
pos += sigParamsSz;
10021014
}
10031015
else
10041016
#endif
10051017
{
10061018
pos += SetAlgoID((int)sigOID, derTmp + pos, oidSigType, 0);
10071019
}
1008-
pos += SetBitString(sigSz, 0, derTmp + pos);
1009-
XMEMCPY(derTmp + pos, sig, sigSz);
1020+
if (ret == 0) {
1021+
pos += SetBitString(sigSz, 0, derTmp + pos);
1022+
XMEMCPY(derTmp + pos, sig, sigSz);
1023+
}
10101024
(void)pos; /* pos not used after this point */
10111025
}
10121026

10131027
/* Determine required PEM size. */
1014-
pemSz = wc_DerToPemEx(derTmp, derNeeded, NULL, 0, NULL, CRL_TYPE);
1015-
if (pemSz < 0) {
1016-
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1017-
return WOLFSSL_FATAL_ERROR;
1018-
}
1019-
if (buff == NULL) {
1020-
*inOutSz = pemSz;
1021-
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1022-
return WOLFSSL_SUCCESS;
1023-
}
1024-
if (outSz < pemSz) {
1025-
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1026-
WOLFSSL_MSG("Output buffer too small for PEM CRL");
1027-
return BUFFER_E;
1028-
}
1029-
if (wc_DerToPemEx(derTmp, derNeeded, buff, (word32)pemSz, NULL,
1030-
CRL_TYPE) < 0) {
1031-
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1032-
return WOLFSSL_FATAL_ERROR;
1028+
if (ret == 0) {
1029+
pemSz = wc_DerToPemEx(derTmp, derNeeded, NULL, 0, NULL, CRL_TYPE);
1030+
if (pemSz < 0) {
1031+
ret = WOLFSSL_FATAL_ERROR;
1032+
}
1033+
else if (buff == NULL) {
1034+
*inOutSz = pemSz;
1035+
ret = WOLFSSL_SUCCESS;
1036+
}
1037+
else if (outSz < pemSz) {
1038+
WOLFSSL_MSG("Output buffer too small for PEM CRL");
1039+
ret = BUFFER_E;
1040+
}
1041+
else if (wc_DerToPemEx(derTmp, derNeeded, buff, (word32)pemSz,
1042+
NULL, CRL_TYPE) < 0) {
1043+
ret = WOLFSSL_FATAL_ERROR;
1044+
}
1045+
else {
1046+
*inOutSz = pemSz;
1047+
ret = WOLFSSL_SUCCESS;
1048+
}
10331049
}
1034-
*inOutSz = pemSz;
1050+
10351051
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1036-
return WOLFSSL_SUCCESS;
10371052
}
10381053
#endif /* WOLFSSL_DER_TO_PEM */
1039-
else {
1040-
return BAD_FUNC_ARG;
1054+
else if (ret == 0) {
1055+
ret = BAD_FUNC_ARG;
10411056
}
1057+
1058+
wc_UnLockRwLock(&crl->crlLock);
1059+
return ret;
10421060
}
10431061

10441062
#ifdef HAVE_CRL_UPDATE_CB
@@ -2302,23 +2320,28 @@ int wolfSSL_X509_CRL_add_revoked(WOLFSSL_X509_CRL* crl,
23022320
{
23032321
const byte* serial = rev->serialNumber->data;
23042322
int serialSz = rev->serialNumber->length;
2323+
int i;
2324+
int allZero = 1;
23052325

23062326
if (serial == NULL || serialSz <= 0) {
23072327
return BAD_FUNC_ARG;
23082328
}
23092329

2310-
/* If the serial is DER-encoded ASN.1 INTEGER, strip tag/length. */
2311-
if (serialSz >= 3 && serial[0] == ASN_INTEGER &&
2312-
serial[1] == serialSz - 2) {
2313-
serial += 2;
2314-
serialSz -= 2;
2330+
if (serialSz > EXTERNAL_SERIAL_SIZE) {
2331+
return BAD_FUNC_ARG;
23152332
}
23162333

2317-
if (serialSz <= 0 || serialSz > EXTERNAL_SERIAL_SIZE) {
2334+
/* All zero serial numbers are invalid per rfc5280 and not supported */
2335+
for (i = 0; i < serialSz; i++) {
2336+
if (serial[i] != 0) {
2337+
allZero = 0;
2338+
break;
2339+
}
2340+
}
2341+
if (allZero) {
23182342
return BAD_FUNC_ARG;
23192343
}
23202344

2321-
/* All zero serial numbers are invalid per rfc5280 and not supported */
23222345
rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), crl->heap,
23232346
DYNAMIC_TYPE_REVOKED);
23242347
if (rc == NULL) {
@@ -2367,7 +2390,6 @@ int wolfSSL_X509_CRL_add_revoked_cert(WOLFSSL_X509_CRL* crl,
23672390
DecodedCert cert[1];
23682391
WOLFSSL_X509_REVOKED revoked;
23692392
WOLFSSL_ASN1_INTEGER* serialInt = NULL;
2370-
int i = 0;
23712393

23722394
WOLFSSL_ENTER("wolfSSL_X509_CRL_add_revoked_cert");
23732395

@@ -2390,26 +2412,24 @@ int wolfSSL_X509_CRL_add_revoked_cert(WOLFSSL_X509_CRL* crl,
23902412
return MEMORY_E;
23912413
}
23922414

2393-
if (cert->serialSz > (WOLFSSL_ASN1_INTEGER_MAX - 2)) {
2394-
serialInt->data = (unsigned char*)XMALLOC(cert->serialSz + 2, NULL,
2415+
if (cert->serialSz > WOLFSSL_ASN1_INTEGER_MAX) {
2416+
serialInt->data = (unsigned char*)XMALLOC(cert->serialSz, NULL,
23952417
DYNAMIC_TYPE_OPENSSL);
23962418
if (serialInt->data == NULL) {
23972419
wolfSSL_ASN1_INTEGER_free(serialInt);
23982420
FreeDecodedCert(cert);
23992421
return MEMORY_E;
24002422
}
2401-
serialInt->dataMax = (unsigned int)cert->serialSz + 2;
2423+
serialInt->dataMax = (unsigned int)cert->serialSz;
24022424
serialInt->isDynamic = 1;
24032425
}
24042426
else {
24052427
serialInt->data = serialInt->intData;
24062428
serialInt->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
24072429
}
24082430

2409-
serialInt->data[i++] = ASN_INTEGER;
2410-
i += SetLength(cert->serialSz, serialInt->data + i);
2411-
XMEMCPY(&serialInt->data[i], cert->serial, cert->serialSz);
2412-
serialInt->length = cert->serialSz + 2;
2431+
XMEMCPY(serialInt->data, cert->serial, cert->serialSz);
2432+
serialInt->length = cert->serialSz;
24132433

24142434
revoked.serialNumber = serialInt;
24152435

0 commit comments

Comments
 (0)