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