andre@0: /* This Source Code Form is subject to the terms of the Mozilla Public andre@0: * License, v. 2.0. If a copy of the MPL was not distributed with this andre@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ andre@0: andre@0: /* andre@0: * Code for dealing with x.509 v3 crl and crl entries extensions. andre@0: */ andre@0: andre@0: #include "cert.h" andre@0: #include "secitem.h" andre@0: #include "secoid.h" andre@0: #include "secoidt.h" andre@0: #include "secder.h" andre@0: #include "secasn1.h" andre@0: #include "certxutl.h" andre@0: andre@0: SECStatus andre@0: CERT_FindCRLExtensionByOID(CERTCrl *crl, SECItem *oid, SECItem *value) andre@0: { andre@0: return (cert_FindExtensionByOID (crl->extensions, oid, value)); andre@0: } andre@0: andre@0: andre@0: SECStatus andre@0: CERT_FindCRLExtension(CERTCrl *crl, int tag, SECItem *value) andre@0: { andre@0: return (cert_FindExtension (crl->extensions, tag, value)); andre@0: } andre@0: andre@0: andre@0: /* Callback to set extensions and adjust verison */ andre@0: static void andre@0: SetCrlExts(void *object, CERTCertExtension **exts) andre@0: { andre@0: CERTCrl *crl = (CERTCrl *)object; andre@0: andre@0: crl->extensions = exts; andre@0: DER_SetUInteger (crl->arena, &crl->version, SEC_CRL_VERSION_2); andre@0: } andre@0: andre@0: void * andre@0: CERT_StartCRLExtensions(CERTCrl *crl) andre@0: { andre@0: return (cert_StartExtensions ((void *)crl, crl->arena, SetCrlExts)); andre@0: } andre@0: andre@0: static void andre@0: SetCrlEntryExts(void *object, CERTCertExtension **exts) andre@0: { andre@0: CERTCrlEntry *crlEntry = (CERTCrlEntry *)object; andre@0: andre@0: crlEntry->extensions = exts; andre@0: } andre@0: andre@0: void * andre@0: CERT_StartCRLEntryExtensions(CERTCrl *crl, CERTCrlEntry *entry) andre@0: { andre@0: return (cert_StartExtensions (entry, crl->arena, SetCrlEntryExts)); andre@0: } andre@0: andre@0: SECStatus CERT_FindCRLNumberExten (PLArenaPool *arena, CERTCrl *crl, andre@0: SECItem *value) andre@0: { andre@0: SECItem encodedExtenValue; andre@0: SECItem *tmpItem = NULL; andre@0: SECStatus rv; andre@0: void *mark = NULL; andre@0: andre@0: encodedExtenValue.data = NULL; andre@0: encodedExtenValue.len = 0; andre@0: andre@0: rv = cert_FindExtension(crl->extensions, SEC_OID_X509_CRL_NUMBER, andre@0: &encodedExtenValue); andre@0: if ( rv != SECSuccess ) andre@0: return (rv); andre@0: andre@0: mark = PORT_ArenaMark(arena); andre@0: andre@0: tmpItem = SECITEM_ArenaDupItem(arena, &encodedExtenValue); andre@0: if (tmpItem) { andre@0: rv = SEC_QuickDERDecodeItem (arena, value, andre@0: SEC_ASN1_GET(SEC_IntegerTemplate), andre@0: tmpItem); andre@0: } else { andre@0: rv = SECFailure; andre@0: } andre@0: andre@0: PORT_Free (encodedExtenValue.data); andre@0: if (rv == SECFailure) { andre@0: PORT_ArenaRelease(arena, mark); andre@0: } else { andre@0: PORT_ArenaUnmark(arena, mark); andre@0: } andre@0: return (rv); andre@0: } andre@0: andre@0: SECStatus CERT_FindCRLEntryReasonExten (CERTCrlEntry *crlEntry, andre@0: CERTCRLEntryReasonCode *value) andre@0: { andre@0: SECItem wrapperItem = {siBuffer,0}; andre@0: SECItem tmpItem = {siBuffer,0}; andre@0: SECStatus rv; andre@0: PLArenaPool *arena = NULL; andre@0: andre@0: arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); andre@0: if ( ! arena ) { andre@0: return(SECFailure); andre@0: } andre@0: andre@0: rv = cert_FindExtension(crlEntry->extensions, SEC_OID_X509_REASON_CODE, andre@0: &wrapperItem); andre@0: if ( rv != SECSuccess ) { andre@0: goto loser; andre@0: } andre@0: andre@0: rv = SEC_QuickDERDecodeItem(arena, &tmpItem, andre@0: SEC_ASN1_GET(SEC_EnumeratedTemplate), andre@0: &wrapperItem); andre@0: andre@0: if ( rv != SECSuccess ) { andre@0: goto loser; andre@0: } andre@0: andre@0: *value = (CERTCRLEntryReasonCode) DER_GetInteger(&tmpItem); andre@0: andre@0: loser: andre@0: if ( arena ) { andre@0: PORT_FreeArena(arena, PR_FALSE); andre@0: } andre@0: andre@0: if ( wrapperItem.data ) { andre@0: PORT_Free(wrapperItem.data); andre@0: } andre@0: andre@0: return (rv); andre@0: } andre@0: andre@0: SECStatus CERT_FindInvalidDateExten (CERTCrl *crl, PRTime *value) andre@0: { andre@0: SECItem encodedExtenValue; andre@0: SECItem decodedExtenValue = {siBuffer,0}; andre@0: SECStatus rv; andre@0: andre@0: encodedExtenValue.data = decodedExtenValue.data = NULL; andre@0: encodedExtenValue.len = decodedExtenValue.len = 0; andre@0: andre@0: rv = cert_FindExtension andre@0: (crl->extensions, SEC_OID_X509_INVALID_DATE, &encodedExtenValue); andre@0: if ( rv != SECSuccess ) andre@0: return (rv); andre@0: andre@0: rv = SEC_ASN1DecodeItem (NULL, &decodedExtenValue, andre@0: SEC_ASN1_GET(SEC_GeneralizedTimeTemplate), andre@0: &encodedExtenValue); andre@0: if (rv == SECSuccess) andre@0: rv = DER_GeneralizedTimeToTime(value, &encodedExtenValue); andre@0: PORT_Free (decodedExtenValue.data); andre@0: PORT_Free (encodedExtenValue.data); andre@0: return (rv); andre@0: }