OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 #include "nspr.h" | 4 #include "nspr.h" |
5 #include "secerr.h" | 5 #include "secerr.h" |
6 #include "secport.h" | 6 #include "secport.h" |
7 #include "seccomon.h" | 7 #include "seccomon.h" |
8 #include "secoid.h" | 8 #include "secoid.h" |
9 #include "sslerr.h" | 9 #include "sslerr.h" |
10 #include "genname.h" | 10 #include "genname.h" |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 SECKEY_DestroyPublicKey(pubKey); | 132 SECKEY_DestroyPublicKey(pubKey); |
133 } | 133 } |
134 return rv; | 134 return rv; |
135 } | 135 } |
136 | 136 |
137 /* | 137 /* |
138 * verify the signature of a signed data object with the given certificate | 138 * verify the signature of a signed data object with the given certificate |
139 */ | 139 */ |
140 SECStatus | 140 SECStatus |
141 CERT_VerifySignedData(CERTSignedData *sd, CERTCertificate *cert, | 141 CERT_VerifySignedData(CERTSignedData *sd, CERTCertificate *cert, |
142 » » int64 t, void *wincx) | 142 » » PRTime t, void *wincx) |
143 { | 143 { |
144 SECKEYPublicKey *pubKey = 0; | 144 SECKEYPublicKey *pubKey = 0; |
145 SECStatus rv = SECFailure; | 145 SECStatus rv = SECFailure; |
146 SECCertTimeValidity validity; | 146 SECCertTimeValidity validity; |
147 | 147 |
148 /* check the certificate's validity */ | 148 /* check the certificate's validity */ |
149 validity = CERT_CheckCertValidTimes(cert, t, PR_FALSE); | 149 validity = CERT_CheckCertValidTimes(cert, t, PR_FALSE); |
150 if ( validity != secCertTimeValid ) { | 150 if ( validity != secCertTimeValid ) { |
151 return rv; | 151 return rv; |
152 } | 152 } |
153 | 153 |
154 /* get cert's public key */ | 154 /* get cert's public key */ |
155 pubKey = CERT_ExtractPublicKey(cert); | 155 pubKey = CERT_ExtractPublicKey(cert); |
156 if (pubKey) { | 156 if (pubKey) { |
157 rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx); | 157 rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx); |
158 SECKEY_DestroyPublicKey(pubKey); | 158 SECKEY_DestroyPublicKey(pubKey); |
159 } | 159 } |
160 return rv; | 160 return rv; |
161 } | 161 } |
162 | 162 |
163 | 163 |
164 SECStatus | 164 SECStatus |
165 SEC_CheckCRL(CERTCertDBHandle *handle,CERTCertificate *cert, | 165 SEC_CheckCRL(CERTCertDBHandle *handle,CERTCertificate *cert, |
166 » CERTCertificate *caCert, int64 t, void * wincx) | 166 » CERTCertificate *caCert, PRTime t, void * wincx) |
167 { | 167 { |
168 return CERT_CheckCRL(cert, caCert, NULL, t, wincx); | 168 return CERT_CheckCRL(cert, caCert, NULL, t, wincx); |
169 } | 169 } |
170 | 170 |
171 /* | 171 /* |
172 * Find the issuer of a cert. Use the authorityKeyID if it exists. | 172 * Find the issuer of a cert. Use the authorityKeyID if it exists. |
173 */ | 173 */ |
174 CERTCertificate * | 174 CERTCertificate * |
175 CERT_FindCertIssuer(CERTCertificate *cert, int64 validTime, SECCertUsage usage) | 175 CERT_FindCertIssuer(CERTCertificate *cert, PRTime validTime, SECCertUsage usage) |
176 { | 176 { |
177 NSSCertificate *me; | 177 NSSCertificate *me; |
178 NSSTime *nssTime; | 178 NSSTime *nssTime; |
179 NSSTrustDomain *td; | 179 NSSTrustDomain *td; |
180 NSSCryptoContext *cc; | 180 NSSCryptoContext *cc; |
181 NSSCertificate *chain[3]; | 181 NSSCertificate *chain[3]; |
182 NSSUsage nssUsage; | 182 NSSUsage nssUsage; |
183 PRStatus status; | 183 PRStatus status; |
184 | 184 |
185 me = STAN_GetNSSCertificate(cert); | 185 me = STAN_GetNSSCertificate(cert); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 | 341 |
342 #define LOG_ERROR(log,cert,depth,arg) \ | 342 #define LOG_ERROR(log,cert,depth,arg) \ |
343 if ( log != NULL ) { \ | 343 if ( log != NULL ) { \ |
344 cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \ | 344 cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \ |
345 (void *)(PRWord)arg); \ | 345 (void *)(PRWord)arg); \ |
346 } | 346 } |
347 | 347 |
348 static SECStatus | 348 static SECStatus |
349 cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert, | 349 cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert, |
350 PRBool checkSig, PRBool* sigerror, | 350 PRBool checkSig, PRBool* sigerror, |
351 SECCertUsage certUsage, int64 t, void *wincx, | 351 SECCertUsage certUsage, PRTime t, void *wincx, |
352 CERTVerifyLog *log, PRBool* revoked) | 352 CERTVerifyLog *log, PRBool* revoked) |
353 { | 353 { |
354 SECTrustType trustType; | 354 SECTrustType trustType; |
355 CERTBasicConstraints basicConstraint; | 355 CERTBasicConstraints basicConstraint; |
356 CERTCertificate *issuerCert = NULL; | 356 CERTCertificate *issuerCert = NULL; |
357 CERTCertificate *subjectCert = NULL; | 357 CERTCertificate *subjectCert = NULL; |
358 CERTCertificate *badCert = NULL; | 358 CERTCertificate *badCert = NULL; |
359 PRBool isca; | 359 PRBool isca; |
360 SECStatus rv; | 360 SECStatus rv; |
361 SECStatus rvFinal = SECSuccess; | 361 SECStatus rvFinal = SECSuccess; |
362 int count; | 362 int count; |
363 int currentPathLen = 0; | 363 int currentPathLen = 0; |
364 int pathLengthLimit = CERT_UNLIMITED_PATH_CONSTRAINT; | 364 int pathLengthLimit = CERT_UNLIMITED_PATH_CONSTRAINT; |
365 unsigned int caCertType; | 365 unsigned int caCertType; |
366 unsigned int requiredCAKeyUsage; | 366 unsigned int requiredCAKeyUsage; |
367 unsigned int requiredFlags; | 367 unsigned int requiredFlags; |
368 PRArenaPool *arena = NULL; | 368 PLArenaPool *arena = NULL; |
369 CERTGeneralName *namesList = NULL; | 369 CERTGeneralName *namesList = NULL; |
370 CERTCertificate **certsList = NULL; | 370 CERTCertificate **certsList = NULL; |
371 int certsListLen = 16; | 371 int certsListLen = 16; |
372 int namesCount = 0; | 372 int namesCount = 0; |
373 PRBool subjectCertIsSelfIssued; | 373 PRBool subjectCertIsSelfIssued; |
374 CERTCertTrust issuerTrust; | 374 CERTCertTrust issuerTrust; |
375 | 375 |
376 if (revoked) { | 376 if (revoked) { |
377 *revoked = PR_FALSE; | 377 *revoked = PR_FALSE; |
378 } | 378 } |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 | 727 |
728 if ( arena != NULL ) { | 728 if ( arena != NULL ) { |
729 PORT_FreeArena(arena, PR_FALSE); | 729 PORT_FreeArena(arena, PR_FALSE); |
730 } | 730 } |
731 return rv; | 731 return rv; |
732 } | 732 } |
733 | 733 |
734 SECStatus | 734 SECStatus |
735 cert_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, | 735 cert_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, |
736 PRBool checkSig, PRBool* sigerror, | 736 PRBool checkSig, PRBool* sigerror, |
737 SECCertUsage certUsage, int64 t, void *wincx, | 737 SECCertUsage certUsage, PRTime t, void *wincx, |
738 CERTVerifyLog *log, PRBool* revoked) | 738 CERTVerifyLog *log, PRBool* revoked) |
739 { | 739 { |
740 if (CERT_GetUsePKIXForValidation()) { | 740 if (CERT_GetUsePKIXForValidation()) { |
741 return cert_VerifyCertChainPkix(cert, checkSig, certUsage, t, | 741 return cert_VerifyCertChainPkix(cert, checkSig, certUsage, t, |
742 wincx, log, sigerror, revoked); | 742 wincx, log, sigerror, revoked); |
743 } | 743 } |
744 return cert_VerifyCertChainOld(handle, cert, checkSig, sigerror, | 744 return cert_VerifyCertChainOld(handle, cert, checkSig, sigerror, |
745 certUsage, t, wincx, log, revoked); | 745 certUsage, t, wincx, log, revoked); |
746 } | 746 } |
747 | 747 |
748 SECStatus | 748 SECStatus |
749 CERT_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, | 749 CERT_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, |
750 » » PRBool checkSig, SECCertUsage certUsage, int64 t, | 750 » » PRBool checkSig, SECCertUsage certUsage, PRTime t, |
751 void *wincx, CERTVerifyLog *log) | 751 void *wincx, CERTVerifyLog *log) |
752 { | 752 { |
753 return cert_VerifyCertChain(handle, cert, checkSig, NULL, certUsage, t, | 753 return cert_VerifyCertChain(handle, cert, checkSig, NULL, certUsage, t, |
754 wincx, log, NULL); | 754 wincx, log, NULL); |
755 } | 755 } |
756 | 756 |
757 /* | 757 /* |
758 * verify that a CA can sign a certificate with the requested usage. | 758 * verify that a CA can sign a certificate with the requested usage. |
759 */ | 759 */ |
760 SECStatus | 760 SECStatus |
761 CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert, | 761 CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert, |
762 » » PRBool checkSig, SECCertUsage certUsage, int64 t, | 762 » » PRBool checkSig, SECCertUsage certUsage, PRTime t, |
763 void *wincx, CERTVerifyLog *log) | 763 void *wincx, CERTVerifyLog *log) |
764 { | 764 { |
765 SECTrustType trustType; | 765 SECTrustType trustType; |
766 CERTBasicConstraints basicConstraint; | 766 CERTBasicConstraints basicConstraint; |
767 PRBool isca; | 767 PRBool isca; |
768 PRBool validCAOverride = PR_FALSE; | 768 PRBool validCAOverride = PR_FALSE; |
769 SECStatus rv; | 769 SECStatus rv; |
770 SECStatus rvFinal = SECSuccess; | 770 SECStatus rvFinal = SECSuccess; |
771 unsigned int flags; | 771 unsigned int flags; |
772 unsigned int caCertType; | 772 unsigned int caCertType; |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1103 * certificateUsage contains a bitfield of all cert usages that are | 1103 * certificateUsage contains a bitfield of all cert usages that are |
1104 * required for verification to succeed | 1104 * required for verification to succeed |
1105 * | 1105 * |
1106 * a bitfield of cert usages is returned in *returnedUsages | 1106 * a bitfield of cert usages is returned in *returnedUsages |
1107 * if requiredUsages is non-zero, the returned bitmap is only | 1107 * if requiredUsages is non-zero, the returned bitmap is only |
1108 * for those required usages, otherwise it is for all usages | 1108 * for those required usages, otherwise it is for all usages |
1109 * | 1109 * |
1110 */ | 1110 */ |
1111 SECStatus | 1111 SECStatus |
1112 CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, | 1112 CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, |
1113 » » PRBool checkSig, SECCertificateUsage requiredUsages, int64 t, | 1113 » » PRBool checkSig, SECCertificateUsage requiredUsages, PRTime t, |
1114 void *wincx, CERTVerifyLog *log, SECCertificateUsage* returnedUs
ages) | 1114 void *wincx, CERTVerifyLog *log, SECCertificateUsage* returnedUs
ages) |
1115 { | 1115 { |
1116 SECStatus rv; | 1116 SECStatus rv; |
1117 SECStatus valid; | 1117 SECStatus valid; |
1118 unsigned int requiredKeyUsage; | 1118 unsigned int requiredKeyUsage; |
1119 unsigned int requiredCertType; | 1119 unsigned int requiredCertType; |
1120 unsigned int flags; | 1120 unsigned int flags; |
1121 unsigned int certType; | 1121 unsigned int certType; |
1122 PRBool allowOverride; | 1122 PRBool allowOverride; |
1123 SECCertTimeValidity validity; | 1123 SECCertTimeValidity validity; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 | 1268 |
1269 NEXT_USAGE(); | 1269 NEXT_USAGE(); |
1270 } | 1270 } |
1271 | 1271 |
1272 loser: | 1272 loser: |
1273 return(valid); | 1273 return(valid); |
1274 } | 1274 } |
1275 | 1275 |
1276 SECStatus | 1276 SECStatus |
1277 CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert, | 1277 CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert, |
1278 » » PRBool checkSig, SECCertUsage certUsage, int64 t, | 1278 » » PRBool checkSig, SECCertUsage certUsage, PRTime t, |
1279 void *wincx, CERTVerifyLog *log) | 1279 void *wincx, CERTVerifyLog *log) |
1280 { | 1280 { |
1281 SECStatus rv; | 1281 SECStatus rv; |
1282 unsigned int requiredKeyUsage; | 1282 unsigned int requiredKeyUsage; |
1283 unsigned int requiredCertType; | 1283 unsigned int requiredCertType; |
1284 unsigned int flags; | 1284 unsigned int flags; |
1285 unsigned int certType; | 1285 unsigned int certType; |
1286 PRBool trusted; | 1286 PRBool trusted; |
1287 PRBool allowOverride; | 1287 PRBool allowOverride; |
1288 SECCertTimeValidity validity; | 1288 SECCertTimeValidity validity; |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1422 * certUsageSSLServer | 1422 * certUsageSSLServer |
1423 * certUsageSSLServerWithStepUp | 1423 * certUsageSSLServerWithStepUp |
1424 * certUsageEmailSigner | 1424 * certUsageEmailSigner |
1425 * certUsageEmailRecipient | 1425 * certUsageEmailRecipient |
1426 * certUsageObjectSigner | 1426 * certUsageObjectSigner |
1427 */ | 1427 */ |
1428 | 1428 |
1429 CERTCertificate * | 1429 CERTCertificate * |
1430 CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName, | 1430 CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName, |
1431 CERTCertOwner owner, SECCertUsage usage, | 1431 CERTCertOwner owner, SECCertUsage usage, |
1432 » » PRBool preferTrusted, int64 validTime, PRBool validOnly) | 1432 » » PRBool preferTrusted, PRTime validTime, PRBool validOnly) |
1433 { | 1433 { |
1434 CERTCertList *certList = NULL; | 1434 CERTCertList *certList = NULL; |
1435 CERTCertificate *cert = NULL; | 1435 CERTCertificate *cert = NULL; |
1436 CERTCertTrust certTrust; | 1436 CERTCertTrust certTrust; |
1437 unsigned int requiredTrustFlags; | 1437 unsigned int requiredTrustFlags; |
1438 SECTrustType requiredTrustType; | 1438 SECTrustType requiredTrustType; |
1439 unsigned int flags; | 1439 unsigned int flags; |
1440 | 1440 |
1441 PRBool lookingForCA = PR_FALSE; | 1441 PRBool lookingForCA = PR_FALSE; |
1442 SECStatus rv; | 1442 SECStatus rv; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1540 CERT_FilterCertListByCANames(CERTCertList *certList, int nCANames, | 1540 CERT_FilterCertListByCANames(CERTCertList *certList, int nCANames, |
1541 char **caNames, SECCertUsage usage) | 1541 char **caNames, SECCertUsage usage) |
1542 { | 1542 { |
1543 CERTCertificate *issuerCert = NULL; | 1543 CERTCertificate *issuerCert = NULL; |
1544 CERTCertificate *subjectCert; | 1544 CERTCertificate *subjectCert; |
1545 CERTCertListNode *node, *freenode; | 1545 CERTCertListNode *node, *freenode; |
1546 CERTCertificate *cert; | 1546 CERTCertificate *cert; |
1547 int n; | 1547 int n; |
1548 char **names; | 1548 char **names; |
1549 PRBool found; | 1549 PRBool found; |
1550 int64 time; | 1550 PRTime time; |
1551 | 1551 |
1552 if ( nCANames <= 0 ) { | 1552 if ( nCANames <= 0 ) { |
1553 return(SECSuccess); | 1553 return(SECSuccess); |
1554 } | 1554 } |
1555 | 1555 |
1556 time = PR_Now(); | 1556 time = PR_Now(); |
1557 | 1557 |
1558 node = CERT_LIST_HEAD(certList); | 1558 node = CERT_LIST_HEAD(certList); |
1559 | 1559 |
1560 while ( ! CERT_LIST_END(node, certList) ) { | 1560 while ( ! CERT_LIST_END(node, certList) ) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1616 * | 1616 * |
1617 * "arena" - arena to allocate returned string from. If NULL, then heap | 1617 * "arena" - arena to allocate returned string from. If NULL, then heap |
1618 * is used. | 1618 * is used. |
1619 * "cert" - the cert to get nickname from | 1619 * "cert" - the cert to get nickname from |
1620 * "expiredString" - the string to append to the nickname if the cert is | 1620 * "expiredString" - the string to append to the nickname if the cert is |
1621 * expired. | 1621 * expired. |
1622 * "notYetGoodString" - the string to append to the nickname if the cert is | 1622 * "notYetGoodString" - the string to append to the nickname if the cert is |
1623 * not yet good. | 1623 * not yet good. |
1624 */ | 1624 */ |
1625 char * | 1625 char * |
1626 CERT_GetCertNicknameWithValidity(PRArenaPool *arena, CERTCertificate *cert, | 1626 CERT_GetCertNicknameWithValidity(PLArenaPool *arena, CERTCertificate *cert, |
1627 char *expiredString, char *notYetGoodString) | 1627 char *expiredString, char *notYetGoodString) |
1628 { | 1628 { |
1629 SECCertTimeValidity validity; | 1629 SECCertTimeValidity validity; |
1630 char *nickname = NULL, *tmpstr = NULL; | 1630 char *nickname = NULL, *tmpstr = NULL; |
1631 | 1631 |
1632 validity = CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE); | 1632 validity = CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE); |
1633 | 1633 |
1634 /* if the cert is good, then just use the nickname directly */ | 1634 /* if the cert is good, then just use the nickname directly */ |
1635 if ( validity == secCertTimeValid ) { | 1635 if ( validity == secCertTimeValid ) { |
1636 if ( arena == NULL ) { | 1636 if ( arena == NULL ) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1688 * "certList" - the list of certificates | 1688 * "certList" - the list of certificates |
1689 * "expiredString" - the string to append to the nickname of any expired cert | 1689 * "expiredString" - the string to append to the nickname of any expired cert |
1690 * "notYetGoodString" - the string to append to the nickname of any cert | 1690 * "notYetGoodString" - the string to append to the nickname of any cert |
1691 * that is not yet valid | 1691 * that is not yet valid |
1692 */ | 1692 */ |
1693 CERTCertNicknames * | 1693 CERTCertNicknames * |
1694 CERT_NicknameStringsFromCertList(CERTCertList *certList, char *expiredString, | 1694 CERT_NicknameStringsFromCertList(CERTCertList *certList, char *expiredString, |
1695 char *notYetGoodString) | 1695 char *notYetGoodString) |
1696 { | 1696 { |
1697 CERTCertNicknames *names; | 1697 CERTCertNicknames *names; |
1698 PRArenaPool *arena; | 1698 PLArenaPool *arena; |
1699 CERTCertListNode *node; | 1699 CERTCertListNode *node; |
1700 char **nn; | 1700 char **nn; |
1701 | 1701 |
1702 /* allocate an arena */ | 1702 /* allocate an arena */ |
1703 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 1703 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
1704 if ( arena == NULL ) { | 1704 if ( arena == NULL ) { |
1705 return(NULL); | 1705 return(NULL); |
1706 } | 1706 } |
1707 | 1707 |
1708 /* allocate the structure */ | 1708 /* allocate the structure */ |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1823 retstr = PORT_Strdup(namestring); | 1823 retstr = PORT_Strdup(namestring); |
1824 | 1824 |
1825 done: | 1825 done: |
1826 return(retstr); | 1826 return(retstr); |
1827 | 1827 |
1828 loser: | 1828 loser: |
1829 return(NULL); | 1829 return(NULL); |
1830 } | 1830 } |
1831 | 1831 |
1832 CERTCertList * | 1832 CERTCertList * |
1833 CERT_GetCertChainFromCert(CERTCertificate *cert, int64 time, SECCertUsage usage) | 1833 CERT_GetCertChainFromCert(CERTCertificate *cert, PRTime time, SECCertUsage usage
) |
1834 { | 1834 { |
1835 CERTCertList *chain = NULL; | 1835 CERTCertList *chain = NULL; |
1836 int count = 0; | 1836 int count = 0; |
1837 | 1837 |
1838 if (NULL == cert) { | 1838 if (NULL == cert) { |
1839 return NULL; | 1839 return NULL; |
1840 } | 1840 } |
1841 | 1841 |
1842 cert = CERT_DupCertificate(cert); | 1842 cert = CERT_DupCertificate(cert); |
1843 if (NULL == cert) { | 1843 if (NULL == cert) { |
(...skipping 19 matching lines...) Expand all Loading... |
1863 return chain; | 1863 return chain; |
1864 } | 1864 } |
1865 | 1865 |
1866 cert = CERT_FindCertIssuer(cert, time, usage); | 1866 cert = CERT_FindCertIssuer(cert, time, usage); |
1867 } | 1867 } |
1868 | 1868 |
1869 /* return partial chain */ | 1869 /* return partial chain */ |
1870 PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); | 1870 PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); |
1871 return chain; | 1871 return chain; |
1872 } | 1872 } |
OLD | NEW |