diff options
author | Konrad Lipinski <k.lipinski2@partner.samsung.com> | 2019-06-11 16:25:51 +0200 |
---|---|---|
committer | Konrad Lipinski <k.lipinski2@samsung.com> | 2019-08-01 14:37:53 +0200 |
commit | cc6febdd37186eeea33bcbce89d79f661ee0009f (patch) | |
tree | 100542f7f8fd3b3c9548150362efe35adde47551 /src/nss/x509vfy.c | |
parent | c40fbfa8503e7763ef630496852f4d6b5e63b58c (diff) | |
download | xmlsec1-cc6febdd37186eeea33bcbce89d79f661ee0009f.tar.gz xmlsec1-cc6febdd37186eeea33bcbce89d79f661ee0009f.tar.bz2 xmlsec1-cc6febdd37186eeea33bcbce89d79f661ee0009f.zip |
Import upstream commit c4d0493d545b99194eea1b2b058930d5a9bb91b1 (1.2.28)
Change-Id: I10f71567cb140be223923e1cd0b5895e366ac23e
Diffstat (limited to 'src/nss/x509vfy.c')
-rw-r--r-- | src/nss/x509vfy.c | 287 |
1 files changed, 105 insertions, 182 deletions
diff --git a/src/nss/x509vfy.c b/src/nss/x509vfy.c index 9e957fea..b5ffc8c4 100644 --- a/src/nss/x509vfy.c +++ b/src/nss/x509vfy.c @@ -1,7 +1,5 @@ -/** - * XMLSec library - * - * X509 support +/* + * XML Security Library (http://www.aleksey.com/xmlsec). * * * This is free software; see Copyright file in the source @@ -9,6 +7,13 @@ * * Copyright (c) 2003 America Online, Inc. All rights reserved. */ +/** + * SECTION:x509vfy + * @Short_description: X509 certificates verification support functions for NSS. + * @Stability: Private + * + */ + #include "globals.h" #ifndef XMLSEC_NO_X509 @@ -168,6 +173,7 @@ xmlSecNssX509StoreVerify(xmlSecKeyDataStorePtr store, CERTCertList* certs, SECStatus status = SECFailure; int64 timeboundary; int64 tmp1, tmp2; + PRErrorCode err; xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecNssX509StoreId), NULL); xmlSecAssert2(certs != NULL, NULL); @@ -176,19 +182,20 @@ xmlSecNssX509StoreVerify(xmlSecKeyDataStorePtr store, CERTCertList* certs, ctx = xmlSecNssX509StoreGetCtx(store); xmlSecAssert2(ctx != NULL, NULL); + if(keyInfoCtx->certsVerificationTime > 0) { + /* convert the time since epoch in seconds to microseconds */ + LL_UI2L(timeboundary, keyInfoCtx->certsVerificationTime); + tmp1 = (int64)PR_USEC_PER_SEC; + tmp2 = timeboundary; + LL_MUL(timeboundary, tmp1, tmp2); + } else { + timeboundary = PR_Now(); + } + for (head = CERT_LIST_HEAD(certs); !CERT_LIST_END(head, certs); head = CERT_LIST_NEXT(head)) { cert = head->cert; - if(keyInfoCtx->certsVerificationTime > 0) { - /* convert the time since epoch in seconds to microseconds */ - LL_UI2L(timeboundary, keyInfoCtx->certsVerificationTime); - tmp1 = (int64)PR_USEC_PER_SEC; - tmp2 = timeboundary; - LL_MUL(timeboundary, tmp1, tmp2); - } else { - timeboundary = PR_Now(); - } /* if cert is the issuer of any other cert in the list, then it is * to be skipped */ @@ -211,11 +218,18 @@ xmlSecNssX509StoreVerify(xmlSecKeyDataStorePtr store, CERTCertList* certs, continue; } - status = CERT_VerifyCertificate(CERT_GetDefaultCertDB(), - cert, PR_FALSE, - (SECCertificateUsage)0, - timeboundary , NULL, NULL, NULL); - if (status == SECSuccess) { + if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS) == 0) { + /* it's important to set the usage here, otherwise no real verification + * is performed. */ + status = CERT_VerifyCertificate(CERT_GetDefaultCertDB(), + cert, PR_FALSE, + certificateUsageEmailSigner, + timeboundary , NULL, NULL, NULL); + if(status == SECSuccess) { + break; + } + } else { + status = SECSuccess; break; } } @@ -224,44 +238,34 @@ xmlSecNssX509StoreVerify(xmlSecKeyDataStorePtr store, CERTCertList* certs, return (cert); } - switch(PORT_GetError()) { + err = PORT_GetError(); + switch(err) { case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: case SEC_ERROR_CA_CERT_INVALID: case SEC_ERROR_UNKNOWN_SIGNER: - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), - NULL, - XMLSEC_ERRORS_R_CERT_ISSUER_FAILED, - "cert with subject name %s could not be verified because the issuer's cert is expired/invalid or not found", - (cert != NULL) ? cert->subjectName : "(NULL)" - ); + xmlSecOtherError2(XMLSEC_ERRORS_R_CERT_ISSUER_FAILED, + xmlSecKeyDataStoreGetName(store), + "subject=\"%s\"; reason=the issuer's cert is expired/invalid or not found", + xmlSecErrorsSafeString(cert->subjectName)); break; case SEC_ERROR_EXPIRED_CERTIFICATE: - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), - NULL, - XMLSEC_ERRORS_R_CERT_HAS_EXPIRED, - "cert with subject name %s has expired", - (cert != NULL) ? cert->subjectName : "(NULL)" - ); + xmlSecOtherError2(XMLSEC_ERRORS_R_CERT_HAS_EXPIRED, + xmlSecKeyDataStoreGetName(store), + "subject=\"%s\"; reason=expired", + xmlSecErrorsSafeString(cert->subjectName)); break; case SEC_ERROR_REVOKED_CERTIFICATE: - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), - NULL, - XMLSEC_ERRORS_R_CERT_REVOKED, - "cert with subject name %s has been revoked", - (cert != NULL) ? cert->subjectName : "(NULL)" - ); + xmlSecOtherError2(XMLSEC_ERRORS_R_CERT_REVOKED, + xmlSecKeyDataStoreGetName(store), + "subject=\"%s\"; reason=revoked", + xmlSecErrorsSafeString(cert->subjectName)); break; default: - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), - NULL, - XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, - "cert with subject name %s could not be verified, errcode %d", - (cert != NULL) ? cert->subjectName : "(NULL)", - PORT_GetError()); + xmlSecOtherError3(XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, + xmlSecKeyDataStoreGetName(store), + "subject=\"%s\"; reason=%d", + xmlSecErrorsSafeString(cert->subjectName), + (int)err); break; } @@ -279,7 +283,7 @@ xmlSecNssX509StoreVerify(xmlSecKeyDataStorePtr store, CERTCertList* certs, * Returns: 0 on success or a negative value if an error occurs. */ int -xmlSecNssX509StoreAdoptCert(xmlSecKeyDataStorePtr store, CERTCertificate* cert, xmlSecKeyDataType type ATTRIBUTE_UNUSED) { +xmlSecNssX509StoreAdoptCert(xmlSecKeyDataStorePtr store, CERTCertificate* cert, xmlSecKeyDataType type) { xmlSecNssX509StoreCtxPtr ctx; int ret; @@ -292,25 +296,34 @@ xmlSecNssX509StoreAdoptCert(xmlSecKeyDataStorePtr store, CERTCertificate* cert, if(ctx->certsList == NULL) { ctx->certsList = CERT_NewCertList(); if(ctx->certsList == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), - "CERT_NewCertList", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "error code=%d", PORT_GetError()); + xmlSecNssError("CERT_NewCertList", xmlSecKeyDataStoreGetName(store)); return(-1); } } ret = CERT_AddCertToListTail(ctx->certsList, cert); if(ret != SECSuccess) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), - "CERT_AddCertToListTail", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "error code=%d", PORT_GetError()); + xmlSecNssError("CERT_AddCertToListTail", xmlSecKeyDataStoreGetName(store)); return(-1); } + if(type == xmlSecKeyDataTypeTrusted) { + SECStatus status; + + /* if requested, mark the certificate as trusted */ + CERTCertTrust trust; + status = CERT_DecodeTrustString(&trust, "TCu,Cu,Tu"); + if(status != SECSuccess) { + xmlSecNssError("CERT_DecodeTrustString", xmlSecKeyDataStoreGetName(store)); + return(-1); + } + CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, &trust); + if(status != SECSuccess) { + xmlSecNssError("CERT_ChangeCertTrust", xmlSecKeyDataStoreGetName(store)); + return(-1); + } + } + return(0); } @@ -364,12 +377,7 @@ xmlSecNssGetCertName(const xmlChar * name) { */ name2 = xmlStrdup(name); if(name2 == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_MALLOC_FAILED, - "xmlStrlen(name)=%d", - xmlStrlen(name)); + xmlSecStrdupError(name, NULL); return(NULL); } while( (p = (xmlChar*)xmlStrstr(name2, BAD_CAST "emailAddress=")) != NULL) { @@ -378,31 +386,23 @@ xmlSecNssGetCertName(const xmlChar * name) { tmp = xmlSecNssX509NameRead(name2, xmlStrlen(name2)); if(tmp == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecNssX509NameRead", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "name2=\"%s\"", - xmlSecErrorsSafeString(name2)); + xmlSecInternalError2("xmlSecNssX509NameRead", NULL, + "name2=\"%s\"", xmlSecErrorsSafeString(name2)); xmlFree(name2); return(NULL); } res = CERT_AsciiToName((char*)tmp); - if (name == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "CERT_AsciiToName", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "ascii=\"%s\", error code=%d", - xmlSecErrorsSafeString((char*)tmp), - PORT_GetError()); + if (res == NULL) { + xmlSecNssError2("CERT_AsciiToName", NULL, + "ascii=\"%s\"", xmlSecErrorsSafeString((char*)tmp)); PORT_Free(tmp); xmlFree(name2); return(NULL); } PORT_Free(tmp); + xmlFree(name2); return(res); } @@ -422,23 +422,16 @@ xmlSecNssX509FindCert(CERTCertList* certsList, const xmlChar *subjectName, if ((cert == NULL) && (subjectName != NULL)) { name = xmlSecNssGetCertName(subjectName); if (name == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecNssGetCertName", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "subject=%s", - xmlSecErrorsSafeString(subjectName)); + xmlSecInternalError2("xmlSecNssGetCertName", NULL, + "subject=%s", + xmlSecErrorsSafeString(subjectName)); goto done; } if(arena == NULL) { arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "PORT_NewArena", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecNssError("PORT_NewArena", NULL); goto done; } } @@ -446,11 +439,7 @@ xmlSecNssX509FindCert(CERTCertList* certsList, const xmlChar *subjectName, nameitem = SEC_ASN1EncodeItem(arena, NULL, (void *)name, SEC_ASN1_GET(CERT_NameTemplate)); if (nameitem == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "SEC_ASN1EncodeItem", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "error code=%d", PORT_GetError()); + xmlSecNssError("SEC_ASN1EncodeItem", NULL); goto done; } @@ -463,23 +452,16 @@ xmlSecNssX509FindCert(CERTCertList* certsList, const xmlChar *subjectName, name = xmlSecNssGetCertName(issuerName); if (name == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecNssGetCertName", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "issuer=%s", - xmlSecErrorsSafeString(issuerName)); + xmlSecInternalError2("xmlSecNssGetCertName", NULL, + "issuer=%s", + xmlSecErrorsSafeString(issuerName)); goto done; } if(arena == NULL) { arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "PORT_NewArena", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecNssError("PORT_NewArena", NULL); goto done; } } @@ -487,11 +469,7 @@ xmlSecNssX509FindCert(CERTCertList* certsList, const xmlChar *subjectName, nameitem = SEC_ASN1EncodeItem(arena, NULL, (void *)name, SEC_ASN1_GET(CERT_NameTemplate)); if (nameitem == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "SEC_ASN1EncodeItem", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "error code=%d", PORT_GetError()); + xmlSecNssError("SEC_ASN1EncodeItem", NULL); goto done; } @@ -502,22 +480,14 @@ xmlSecNssX509FindCert(CERTCertList* certsList, const xmlChar *subjectName, /* TBD: serial num can be arbitrarily long */ if(PR_sscanf((char *)issuerSerial, "%llu", &issuerSN) != 1) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "PR_sscanf", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "error code=%d", PR_GetError()); + xmlSecNssError("PR_sscanf(issuerSerial)", NULL); SECITEM_FreeItem(&issuerAndSN.serialNumber, PR_FALSE); goto done; } rv = xmlSecNssNumToItem(&issuerAndSN.serialNumber, issuerSN); if(rv <= 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecNssNumToItem", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "error code=%d", PR_GetError()); + xmlSecInternalError("xmlSecNssNumToItem(serialNumber)", NULL); SECITEM_FreeItem(&issuerAndSN.serialNumber, PR_FALSE); goto done; } @@ -532,12 +502,7 @@ xmlSecNssX509FindCert(CERTCertList* certsList, const xmlChar *subjectName, len = xmlSecBase64Decode(ski, (xmlSecByte*)ski, xmlStrlen(ski)); if(len < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecBase64Decode", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "ski=%s", - xmlSecErrorsSafeString(ski)); + xmlSecInternalError("xmlSecBase64Decode", NULL); goto done; } @@ -561,11 +526,7 @@ xmlSecNssX509FindCert(CERTCertList* certsList, const xmlChar *subjectName, memset(&tmpitem, 0, sizeof(tmpitem)); status = CERT_FindSubjectKeyIDExtension(head->cert, &tmpitem); if (status != SECSuccess) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "CERT_FindSubjectKeyIDExtension", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "ski"); + xmlSecNssError("CERT_FindSubjectKeyIDExtension(ski)", NULL); SECITEM_FreeItem(&tmpitem, PR_FALSE); goto done; } @@ -575,11 +536,7 @@ xmlSecNssX509FindCert(CERTCertList* certsList, const xmlChar *subjectName, ) { cert = CERT_DupCertificate(head->cert); if(cert == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "CERT_DupCertificate", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - "error code=%d", PORT_GetError()); + xmlSecNssError("CERT_DupCertificate", NULL); SECITEM_FreeItem(&tmpitem, PR_FALSE); goto done; } @@ -613,11 +570,8 @@ xmlSecNssX509NameRead(xmlSecByte *str, int len) { /* return string should be no longer than input string */ retval = (xmlSecByte *)PORT_Alloc(len+1); if(retval == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "PORT_Alloc", - XMLSEC_ERRORS_R_MALLOC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecNssError2("PORT_Alloc", NULL, + "size=%d", (len+1)); return(NULL); } p = retval; @@ -630,11 +584,7 @@ xmlSecNssX509NameRead(xmlSecByte *str, int len) { nameLen = xmlSecNssX509NameStringRead(&str, &len, name, sizeof(name), '=', 0); if(nameLen < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecNssX509NameStringRead", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInternalError("xmlSecNssX509NameStringRead", NULL); goto done; } memcpy(p, name, nameLen); @@ -646,11 +596,7 @@ xmlSecNssX509NameRead(xmlSecByte *str, int len) { valueLen = xmlSecNssX509NameStringRead(&str, &len, value, sizeof(value), '"', 1); if(valueLen < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecNssX509NameStringRead", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInternalError("xmlSecNssX509NameStringRead", NULL); goto done; } /* skip spaces before comma or semicolon */ @@ -658,11 +604,7 @@ xmlSecNssX509NameRead(xmlSecByte *str, int len) { ++str; --len; } if((len > 0) && ((*str) != ',')) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_INVALID_DATA, - "comma is expected"); + xmlSecInvalidIntegerDataError("char", (*str), "comma ','", NULL); goto done; } if(len > 0) { @@ -674,21 +616,13 @@ xmlSecNssX509NameRead(xmlSecByte *str, int len) { *p++='\"'; } else if((*str) == '#') { /* TODO: read octect values */ - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_INVALID_DATA, - "reading octect values is not implemented yet"); + xmlSecNotImplementedError("reading octect values is not implemented yet"); goto done; } else { valueLen = xmlSecNssX509NameStringRead(&str, &len, value, sizeof(value), ',', 1); if(valueLen < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecNssX509NameStringRead", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInternalError("xmlSecNssX509NameStringRead", NULL); goto done; } memcpy(p, value, valueLen); @@ -734,22 +668,14 @@ xmlSecNssX509NameStringRead(xmlSecByte **str, int *strLen, nonSpace = q; if(xmlSecIsHex((*p))) { if((p - (*str) + 1) >= (*strLen)) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_INVALID_DATA, - "two hex digits expected"); + xmlSecInvalidDataError("two hex digits expected", NULL); return(-1); } *(q++) = xmlSecGetHex(p[0]) * 16 + xmlSecGetHex(p[1]); p += 2; } else { if(((++p) - (*str)) >= (*strLen)) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_INVALID_DATA, - "escaped symbol missed"); + xmlSecInvalidDataError("escaped symbol missed", NULL); return(-1); } *(q++) = *(p++); @@ -757,11 +683,7 @@ xmlSecNssX509NameStringRead(xmlSecByte **str, int *strLen, } } if(((p - (*str)) < (*strLen)) && ((*p) != delim)) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_INVALID_SIZE, - "buffer is too small"); + xmlSecInvalidSizeOtherError("buffer is too small", NULL); return(-1); } (*strLen) -= (p - (*str)); @@ -793,7 +715,8 @@ xmlSecNssNumToItem(SECItem *it, PRUint64 ui) ** require progressively more space. Start from 1 because byte at ** position 0 is zero */ - for(zeros_len = 1; (zeros_len < sizeof(bb)) && (bb[zeros_len] == 0); ++zeros_len); + for(zeros_len = 1; (zeros_len < sizeof(bb)) && (bb[zeros_len] == 0); ++zeros_len) { + } it->len = sizeof(bb) - (zeros_len - 1); it->data = (unsigned char *)PORT_Alloc(it->len); |