summaryrefslogtreecommitdiff
path: root/src/nss/x509vfy.c
diff options
context:
space:
mode:
authorKonrad Lipinski <k.lipinski2@partner.samsung.com>2019-06-11 16:25:51 +0200
committerKonrad Lipinski <k.lipinski2@samsung.com>2019-08-01 14:37:53 +0200
commitcc6febdd37186eeea33bcbce89d79f661ee0009f (patch)
tree100542f7f8fd3b3c9548150362efe35adde47551 /src/nss/x509vfy.c
parentc40fbfa8503e7763ef630496852f4d6b5e63b58c (diff)
downloadxmlsec1-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.c287
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);