/* * get the value of the X.509 v3 Key Usage Extension */ SECStatus CERT_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem) { SECStatus rv; SECItem encodedValue = {siBuffer, NULL, 0 }; SECItem decodedValue = {siBuffer, NULL, 0 }; rv = cert_FindExtension (cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID, &encodedValue); if (rv == SECSuccess) { PLArenaPool * tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (tmpArena) { rv = SEC_QuickDERDecodeItem(tmpArena, &decodedValue, SEC_ASN1_GET(SEC_OctetStringTemplate), &encodedValue); if (rv == SECSuccess) { rv = SECITEM_CopyItem(NULL, retItem, &decodedValue); } PORT_FreeArena(tmpArena, PR_FALSE); } else { rv = SECFailure; } } SECITEM_FreeItem(&encodedValue, PR_FALSE); return rv; }
SECStatus CERT_FindCRLNumberExten (PRArenaPool *arena, CERTCrl *crl, SECItem *value) { SECItem encodedExtenValue; SECItem *tmpItem = NULL; SECStatus rv; void *mark = NULL; encodedExtenValue.data = NULL; encodedExtenValue.len = 0; rv = cert_FindExtension(crl->extensions, SEC_OID_X509_CRL_NUMBER, &encodedExtenValue); if ( rv != SECSuccess ) return (rv); mark = PORT_ArenaMark(arena); tmpItem = SECITEM_ArenaDupItem(arena, &encodedExtenValue); if (tmpItem) { rv = SEC_QuickDERDecodeItem (arena, value, SEC_ASN1_GET(SEC_IntegerTemplate), tmpItem); } else { rv = SECFailure; } PORT_Free (encodedExtenValue.data); if (rv == SECFailure) { PORT_ArenaRelease(arena, mark); } else { PORT_ArenaUnmark(arena, mark); } return (rv); }
/* * get the value of a string type extension */ char * CERT_FindNSStringExtension(CERTCertificate *cert, int oidtag) { SECItem wrapperItem, tmpItem = {siBuffer,0}; SECStatus rv; PLArenaPool *arena = NULL; char *retstring = NULL; wrapperItem.data = NULL; tmpItem.data = NULL; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( ! arena ) { goto loser; } rv = cert_FindExtension(cert->extensions, oidtag, &wrapperItem); if ( rv != SECSuccess ) { goto loser; } rv = SEC_QuickDERDecodeItem(arena, &tmpItem, SEC_ASN1_GET(SEC_IA5StringTemplate), &wrapperItem); if ( rv != SECSuccess ) { goto loser; } retstring = (char *)PORT_Alloc(tmpItem.len + 1 ); if ( retstring == NULL ) { goto loser; } PORT_Memcpy(retstring, tmpItem.data, tmpItem.len); retstring[tmpItem.len] = '\0'; loser: if ( arena ) { PORT_FreeArena(arena, PR_FALSE); } if ( wrapperItem.data ) { PORT_Free(wrapperItem.data); } return(retstring); }
/* find the given extension in the certificate of the Issuer of 'cert' */ SECStatus CERT_FindIssuerCertExtension(CERTCertificate *cert, int tag, SECItem *value) { CERTCertificate *issuercert; SECStatus rv; issuercert = CERT_FindCertByName(cert->dbhandle, &cert->derIssuer); if ( issuercert ) { rv = cert_FindExtension(issuercert->extensions, tag, value); CERT_DestroyCertificate(issuercert); } else { rv = SECFailure; } return(rv); }
SECStatus CERT_FindCRLEntryReasonExten (CERTCrlEntry *crlEntry, CERTCRLEntryReasonCode *value) { SECItem wrapperItem = {siBuffer,0}; SECItem tmpItem = {siBuffer,0}; SECStatus rv; PRArenaPool *arena = NULL; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( ! arena ) { return(SECFailure); } rv = cert_FindExtension(crlEntry->extensions, SEC_OID_X509_REASON_CODE, &wrapperItem); if ( rv != SECSuccess ) { goto loser; } rv = SEC_QuickDERDecodeItem(arena, &tmpItem, SEC_ASN1_GET(SEC_EnumeratedTemplate), &wrapperItem); if ( rv != SECSuccess ) { goto loser; } *value = (CERTCRLEntryReasonCode) DER_GetInteger(&tmpItem); loser: if ( arena ) { PORT_FreeArena(arena, PR_FALSE); } if ( wrapperItem.data ) { PORT_Free(wrapperItem.data); } return (rv); }
CERTCrlDistributionPoints * CERT_FindCRLDistributionPoints (CERTCertificate *cert) { SECItem encodedExtenValue; SECStatus rv; CERTCrlDistributionPoints *dps; encodedExtenValue.data = NULL; encodedExtenValue.len = 0; rv = cert_FindExtension(cert->extensions, SEC_OID_X509_CRL_DIST_POINTS, &encodedExtenValue); if ( rv != SECSuccess ) { return (NULL); } dps = CERT_DecodeCRLDistributionPoints(cert->arena, &encodedExtenValue); PORT_Free(encodedExtenValue.data); return dps; }
CERTAuthKeyID * CERT_FindAuthKeyIDExten (PLArenaPool *arena, CERTCertificate *cert) { SECItem encodedExtenValue; SECStatus rv; CERTAuthKeyID *ret; encodedExtenValue.data = NULL; encodedExtenValue.len = 0; rv = cert_FindExtension(cert->extensions, SEC_OID_X509_AUTH_KEY_ID, &encodedExtenValue); if ( rv != SECSuccess ) { return (NULL); } ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue); PORT_Free(encodedExtenValue.data); encodedExtenValue.data = NULL; return(ret); }
SECStatus CERT_FindInvalidDateExten (CERTCrl *crl, int64 *value) { SECItem encodedExtenValue; SECItem decodedExtenValue = {siBuffer,0}; SECStatus rv; encodedExtenValue.data = decodedExtenValue.data = NULL; encodedExtenValue.len = decodedExtenValue.len = 0; rv = cert_FindExtension (crl->extensions, SEC_OID_X509_INVALID_DATE, &encodedExtenValue); if ( rv != SECSuccess ) return (rv); rv = SEC_ASN1DecodeItem (NULL, &decodedExtenValue, SEC_ASN1_GET(SEC_GeneralizedTimeTemplate), &encodedExtenValue); if (rv == SECSuccess) rv = DER_GeneralizedTimeToTime(value, &encodedExtenValue); PORT_Free (decodedExtenValue.data); PORT_Free (encodedExtenValue.data); return (rv); }
SECStatus CERT_FindBasicConstraintExten(CERTCertificate *cert, CERTBasicConstraints *value) { SECItem encodedExtenValue; SECStatus rv; encodedExtenValue.data = NULL; encodedExtenValue.len = 0; rv = cert_FindExtension(cert->extensions, SEC_OID_X509_BASIC_CONSTRAINTS, &encodedExtenValue); if ( rv != SECSuccess ) { return (rv); } rv = CERT_DecodeBasicConstraintValue (value, &encodedExtenValue); /* free the raw extension data */ PORT_Free(encodedExtenValue.data); encodedExtenValue.data = NULL; return(rv); }
/* find a URL extension in the cert */ char * CERT_FindCertURLExtension(CERTCertificate *cert, SECOidTag tag) { SECStatus rv; SECItem urlitem = {siBuffer,0}; SECItem urlstringitem = {siBuffer,0}; PLArenaPool *arena = NULL; char *urlstring = NULL; char *str; int len; if (!cert) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( ! arena ) { goto loser; } rv = cert_FindExtension(cert->extensions, tag, &urlitem); if ( rv != SECSuccess ) { goto loser; } rv = SEC_QuickDERDecodeItem(arena, &urlstringitem, SEC_ASN1_GET(SEC_IA5StringTemplate), &urlitem); if ( rv != SECSuccess ) { goto loser; } len = urlstringitem.len + 1; str = urlstring = (char *)PORT_Alloc(len); if ( urlstring == NULL ) { goto loser; } /* copy the URL */ PORT_Memcpy(str, urlstringitem.data, urlstringitem.len); str += urlstringitem.len; *str = '\0'; goto done; loser: if ( urlstring ) { PORT_Free(urlstring); } urlstring = NULL; done: if ( arena ) { PORT_FreeArena(arena, PR_FALSE); } if ( urlitem.data ) { PORT_Free(urlitem.data); } return(urlstring); }
SECStatus CERT_FindCertExtension(const CERTCertificate *cert, int tag, SECItem *value) { return (cert_FindExtension (cert->extensions, tag, value)); }
SECStatus CERT_FindCRLExtension(CERTCrl *crl, int tag, SECItem *value) { return (cert_FindExtension (crl->extensions, tag, value)); }
/* find a URL extension in the cert or its CA * apply the base URL string if it exists */ char * CERT_FindCertURLExtension(CERTCertificate *cert, int tag, int catag) { SECStatus rv; SECItem urlitem = {siBuffer,0}; SECItem baseitem = {siBuffer,0}; SECItem urlstringitem = {siBuffer,0}; SECItem basestringitem = {siBuffer,0}; PRArenaPool *arena = NULL; PRBool hasbase; char *urlstring; char *str; int len; unsigned int i; urlstring = NULL; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( ! arena ) { goto loser; } hasbase = PR_FALSE; rv = cert_FindExtension(cert->extensions, tag, &urlitem); if ( rv == SECSuccess ) { rv = cert_FindExtension(cert->extensions, SEC_OID_NS_CERT_EXT_BASE_URL, &baseitem); if ( rv == SECSuccess ) { hasbase = PR_TRUE; } } else if ( catag ) { /* if the cert doesn't have the extensions, see if the issuer does */ rv = CERT_FindIssuerCertExtension(cert, catag, &urlitem); if ( rv != SECSuccess ) { goto loser; } rv = CERT_FindIssuerCertExtension(cert, SEC_OID_NS_CERT_EXT_BASE_URL, &baseitem); if ( rv == SECSuccess ) { hasbase = PR_TRUE; } } else { goto loser; } rv = SEC_QuickDERDecodeItem(arena, &urlstringitem, SEC_ASN1_GET(SEC_IA5StringTemplate), &urlitem); if ( rv != SECSuccess ) { goto loser; } if ( hasbase ) { rv = SEC_QuickDERDecodeItem(arena, &basestringitem, SEC_ASN1_GET(SEC_IA5StringTemplate), &baseitem); if ( rv != SECSuccess ) { goto loser; } } len = urlstringitem.len + ( hasbase ? basestringitem.len : 0 ) + 1; str = urlstring = (char *)PORT_Alloc(len); if ( urlstring == NULL ) { goto loser; } /* copy the URL base first */ if ( hasbase ) { /* if the urlstring has a : in it, then we assume it is an absolute * URL, and will not get the base string pre-pended */ for ( i = 0; i < urlstringitem.len; i++ ) { if ( urlstringitem.data[i] == ':' ) { goto nobase; } } PORT_Memcpy(str, basestringitem.data, basestringitem.len); str += basestringitem.len; } nobase: /* copy the rest (or all) of the URL */ PORT_Memcpy(str, urlstringitem.data, urlstringitem.len); str += urlstringitem.len; *str = '\0'; goto done; loser: if ( urlstring ) { PORT_Free(urlstring); } urlstring = NULL; done: if ( arena ) { PORT_FreeArena(arena, PR_FALSE); } if ( baseitem.data ) { PORT_Free(baseitem.data); } if ( urlitem.data ) { PORT_Free(urlitem.data); } return(urlstring); }