Mercurial > trustbridge > nss-cmake-static
diff nss/lib/certdb/polcyxtn.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nss/lib/certdb/polcyxtn.c Mon Jul 28 10:47:06 2014 +0200 @@ -0,0 +1,829 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Support for various policy related extensions + */ + +#include "seccomon.h" +#include "secport.h" +#include "secder.h" +#include "cert.h" +#include "secoid.h" +#include "secasn1.h" +#include "secerr.h" +#include "nspr.h" + +SEC_ASN1_MKSUB(SEC_IntegerTemplate) +SEC_ASN1_MKSUB(SEC_ObjectIDTemplate) + +const SEC_ASN1Template CERT_DisplayTextTypeTemplate[] = { + { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) }, + { SEC_ASN1_IA5_STRING, 0, 0, siAsciiString}, + { SEC_ASN1_VISIBLE_STRING , 0, 0, siVisibleString}, + { SEC_ASN1_BMP_STRING , 0, 0, siBMPString }, + { SEC_ASN1_UTF8_STRING , 0, 0, siUTF8String }, + { 0 } +}; + +const SEC_ASN1Template CERT_NoticeReferenceTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(CERTNoticeReference) }, + { SEC_ASN1_INLINE, + offsetof(CERTNoticeReference, organization), + CERT_DisplayTextTypeTemplate, 0 }, + { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, + offsetof(CERTNoticeReference, noticeNumbers), + SEC_ASN1_SUB(SEC_IntegerTemplate) }, + { 0 } +}; + +const SEC_ASN1Template CERT_UserNoticeTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(CERTUserNotice) }, + { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL, + offsetof(CERTUserNotice, noticeReference), + CERT_NoticeReferenceTemplate, 0 }, + { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL, + offsetof(CERTUserNotice, displayText), + CERT_DisplayTextTypeTemplate, 0 }, + { 0 } +}; + +const SEC_ASN1Template CERT_PolicyQualifierTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(CERTPolicyQualifier) }, + { SEC_ASN1_OBJECT_ID, + offsetof(CERTPolicyQualifier, qualifierID) }, + { SEC_ASN1_ANY, + offsetof(CERTPolicyQualifier, qualifierValue) }, + { 0 } +}; + +const SEC_ASN1Template CERT_PolicyInfoTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(CERTPolicyInfo) }, + { SEC_ASN1_OBJECT_ID, + offsetof(CERTPolicyInfo, policyID) }, + { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_OPTIONAL, + offsetof(CERTPolicyInfo, policyQualifiers), + CERT_PolicyQualifierTemplate }, + { 0 } +}; + +const SEC_ASN1Template CERT_CertificatePoliciesTemplate[] = { + { SEC_ASN1_SEQUENCE_OF, + offsetof(CERTCertificatePolicies, policyInfos), + CERT_PolicyInfoTemplate, sizeof(CERTCertificatePolicies) } +}; + +const SEC_ASN1Template CERT_PolicyMapTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(CERTPolicyMap) }, + { SEC_ASN1_OBJECT_ID, + offsetof(CERTPolicyMap, issuerDomainPolicy) }, + { SEC_ASN1_OBJECT_ID, + offsetof(CERTPolicyMap, subjectDomainPolicy) }, + { 0 } +}; + +const SEC_ASN1Template CERT_PolicyMappingsTemplate[] = { + { SEC_ASN1_SEQUENCE_OF, + offsetof(CERTCertificatePolicyMappings, policyMaps), + CERT_PolicyMapTemplate, sizeof(CERTPolicyMap) } +}; + +const SEC_ASN1Template CERT_PolicyConstraintsTemplate[] = { + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCertificatePolicyConstraints) }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, + offsetof(CERTCertificatePolicyConstraints, explicitPolicySkipCerts), + SEC_ASN1_SUB(SEC_IntegerTemplate) }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, + offsetof(CERTCertificatePolicyConstraints, inhibitMappingSkipCerts), + SEC_ASN1_SUB(SEC_IntegerTemplate) }, + { 0 } +}; + +const SEC_ASN1Template CERT_InhibitAnyTemplate[] = { + { SEC_ASN1_INTEGER, + offsetof(CERTCertificateInhibitAny, inhibitAnySkipCerts), + NULL, sizeof(CERTCertificateInhibitAny) } +}; + +static void +breakLines(char *string) +{ + char *tmpstr; + char *lastspace = NULL; + int curlen = 0; + int c; + + tmpstr = string; + + while ( ( c = *tmpstr ) != '\0' ) { + switch ( c ) { + case ' ': + lastspace = tmpstr; + break; + case '\n': + lastspace = NULL; + curlen = 0; + break; + } + + if ( ( curlen >= 55 ) && ( lastspace != NULL ) ) { + *lastspace = '\n'; + curlen = ( tmpstr - lastspace ); + lastspace = NULL; + } + + curlen++; + tmpstr++; + } + + return; +} + +CERTCertificatePolicies * +CERT_DecodeCertificatePoliciesExtension(const SECItem *extnValue) +{ + PLArenaPool *arena = NULL; + SECStatus rv; + CERTCertificatePolicies *policies; + CERTPolicyInfo **policyInfos, *policyInfo; + CERTPolicyQualifier **policyQualifiers, *policyQualifier; + SECItem newExtnValue; + + /* make a new arena */ + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + + if ( !arena ) { + goto loser; + } + + /* allocate the certificate policies structure */ + policies = (CERTCertificatePolicies *) + PORT_ArenaZAlloc(arena, sizeof(CERTCertificatePolicies)); + + if ( policies == NULL ) { + goto loser; + } + + policies->arena = arena; + + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue); + if ( rv != SECSuccess ) { + goto loser; + } + + /* decode the policy info */ + rv = SEC_QuickDERDecodeItem(arena, policies, CERT_CertificatePoliciesTemplate, + &newExtnValue); + + if ( rv != SECSuccess ) { + goto loser; + } + + /* initialize the oid tags */ + policyInfos = policies->policyInfos; + while (*policyInfos != NULL ) { + policyInfo = *policyInfos; + policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID); + policyQualifiers = policyInfo->policyQualifiers; + while ( policyQualifiers != NULL && *policyQualifiers != NULL ) { + policyQualifier = *policyQualifiers; + policyQualifier->oid = + SECOID_FindOIDTag(&policyQualifier->qualifierID); + policyQualifiers++; + } + policyInfos++; + } + + return(policies); + +loser: + if ( arena != NULL ) { + PORT_FreeArena(arena, PR_FALSE); + } + + return(NULL); +} + +void +CERT_DestroyCertificatePoliciesExtension(CERTCertificatePolicies *policies) +{ + if ( policies != NULL ) { + PORT_FreeArena(policies->arena, PR_FALSE); + } + return; +} + +CERTCertificatePolicyMappings * +CERT_DecodePolicyMappingsExtension(SECItem *extnValue) +{ + PLArenaPool *arena = NULL; + SECStatus rv; + CERTCertificatePolicyMappings *mappings; + SECItem newExtnValue; + + /* make a new arena */ + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if ( !arena ) { + goto loser; + } + + /* allocate the policy mappings structure */ + mappings = (CERTCertificatePolicyMappings *) + PORT_ArenaZAlloc(arena, sizeof(CERTCertificatePolicyMappings)); + if ( mappings == NULL ) { + goto loser; + } + mappings->arena = arena; + + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue); + if ( rv != SECSuccess ) { + goto loser; + } + + /* decode the policy mappings */ + rv = SEC_QuickDERDecodeItem + (arena, mappings, CERT_PolicyMappingsTemplate, &newExtnValue); + if ( rv != SECSuccess ) { + goto loser; + } + + return(mappings); + +loser: + if ( arena != NULL ) { + PORT_FreeArena(arena, PR_FALSE); + } + + return(NULL); +} + +SECStatus +CERT_DestroyPolicyMappingsExtension(CERTCertificatePolicyMappings *mappings) +{ + if ( mappings != NULL ) { + PORT_FreeArena(mappings->arena, PR_FALSE); + } + return SECSuccess; +} + +SECStatus +CERT_DecodePolicyConstraintsExtension + (CERTCertificatePolicyConstraints *decodedValue, + const SECItem *encodedValue) +{ + CERTCertificatePolicyConstraints decodeContext; + PLArenaPool *arena = NULL; + SECStatus rv = SECSuccess; + + /* initialize so we can tell when an optional component is omitted */ + PORT_Memset(&decodeContext, 0, sizeof(decodeContext)); + + /* make a new arena */ + arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); + if (!arena) { + return SECFailure; + } + + do { + /* decode the policy constraints */ + rv = SEC_QuickDERDecodeItem(arena, + &decodeContext, CERT_PolicyConstraintsTemplate, encodedValue); + + if ( rv != SECSuccess ) { + break; + } + + if (decodeContext.explicitPolicySkipCerts.len == 0) { + *(PRInt32 *)decodedValue->explicitPolicySkipCerts.data = -1; + } else { + *(PRInt32 *)decodedValue->explicitPolicySkipCerts.data = + DER_GetInteger(&decodeContext.explicitPolicySkipCerts); + } + + if (decodeContext.inhibitMappingSkipCerts.len == 0) { + *(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data = -1; + } else { + *(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data = + DER_GetInteger(&decodeContext.inhibitMappingSkipCerts); + } + + if ((*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data == + PR_INT32_MIN) || + (*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data == + PR_INT32_MAX) || + (*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data == + PR_INT32_MIN) || + (*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data == + PR_INT32_MAX)) { + rv = SECFailure; + } + + } while (0); + + PORT_FreeArena(arena, PR_FALSE); + return(rv); +} + +SECStatus CERT_DecodeInhibitAnyExtension + (CERTCertificateInhibitAny *decodedValue, SECItem *encodedValue) +{ + CERTCertificateInhibitAny decodeContext; + PLArenaPool *arena = NULL; + SECStatus rv = SECSuccess; + + /* make a new arena */ + arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); + if ( !arena ) { + return SECFailure; + } + + do { + + /* decode the policy mappings */ + decodeContext.inhibitAnySkipCerts.type = siUnsignedInteger; + rv = SEC_QuickDERDecodeItem(arena, + &decodeContext, CERT_InhibitAnyTemplate, encodedValue); + + if ( rv != SECSuccess ) { + break; + } + + *(PRInt32 *)decodedValue->inhibitAnySkipCerts.data = + DER_GetInteger(&decodeContext.inhibitAnySkipCerts); + + } while (0); + + PORT_FreeArena(arena, PR_FALSE); + return(rv); +} + +CERTUserNotice * +CERT_DecodeUserNotice(SECItem *noticeItem) +{ + PLArenaPool *arena = NULL; + SECStatus rv; + CERTUserNotice *userNotice; + SECItem newNoticeItem; + + /* make a new arena */ + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + + if ( !arena ) { + goto loser; + } + + /* allocate the userNotice structure */ + userNotice = (CERTUserNotice *)PORT_ArenaZAlloc(arena, + sizeof(CERTUserNotice)); + + if ( userNotice == NULL ) { + goto loser; + } + + userNotice->arena = arena; + + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newNoticeItem, noticeItem); + if ( rv != SECSuccess ) { + goto loser; + } + + /* decode the user notice */ + rv = SEC_QuickDERDecodeItem(arena, userNotice, CERT_UserNoticeTemplate, + &newNoticeItem); + + if ( rv != SECSuccess ) { + goto loser; + } + + if (userNotice->derNoticeReference.data != NULL) { + + rv = SEC_QuickDERDecodeItem(arena, &userNotice->noticeReference, + CERT_NoticeReferenceTemplate, + &userNotice->derNoticeReference); + if (rv == SECFailure) { + goto loser; + } + } + + return(userNotice); + +loser: + if ( arena != NULL ) { + PORT_FreeArena(arena, PR_FALSE); + } + + return(NULL); +} + +void +CERT_DestroyUserNotice(CERTUserNotice *userNotice) +{ + if ( userNotice != NULL ) { + PORT_FreeArena(userNotice->arena, PR_FALSE); + } + return; +} + +static CERTPolicyStringCallback policyStringCB = NULL; +static void *policyStringCBArg = NULL; + +void +CERT_SetCAPolicyStringCallback(CERTPolicyStringCallback cb, void *cbarg) +{ + policyStringCB = cb; + policyStringCBArg = cbarg; + return; +} + +char * +stringFromUserNotice(SECItem *noticeItem) +{ + SECItem *org; + unsigned int len, headerlen; + char *stringbuf; + CERTUserNotice *userNotice; + char *policystr; + char *retstr = NULL; + SECItem *displayText; + SECItem **noticeNumbers; + unsigned int strnum; + + /* decode the user notice */ + userNotice = CERT_DecodeUserNotice(noticeItem); + if ( userNotice == NULL ) { + return(NULL); + } + + org = &userNotice->noticeReference.organization; + if ( (org->len != 0 ) && ( policyStringCB != NULL ) ) { + /* has a noticeReference */ + + /* extract the org string */ + len = org->len; + stringbuf = (char*)PORT_Alloc(len + 1); + if ( stringbuf != NULL ) { + PORT_Memcpy(stringbuf, org->data, len); + stringbuf[len] = '\0'; + + noticeNumbers = userNotice->noticeReference.noticeNumbers; + while ( *noticeNumbers != NULL ) { + /* XXX - only one byte integers right now*/ + strnum = (*noticeNumbers)->data[0]; + policystr = (* policyStringCB)(stringbuf, + strnum, + policyStringCBArg); + if ( policystr != NULL ) { + if ( retstr != NULL ) { + retstr = PR_sprintf_append(retstr, "\n%s", policystr); + } else { + retstr = PR_sprintf_append(retstr, "%s", policystr); + } + + PORT_Free(policystr); + } + + noticeNumbers++; + } + + PORT_Free(stringbuf); + } + } + + if ( retstr == NULL ) { + if ( userNotice->displayText.len != 0 ) { + displayText = &userNotice->displayText; + + if ( displayText->len > 2 ) { + if ( displayText->data[0] == SEC_ASN1_VISIBLE_STRING ) { + headerlen = 2; + if ( displayText->data[1] & 0x80 ) { + /* multibyte length */ + headerlen += ( displayText->data[1] & 0x7f ); + } + + len = displayText->len - headerlen; + retstr = (char*)PORT_Alloc(len + 1); + if ( retstr != NULL ) { + PORT_Memcpy(retstr, &displayText->data[headerlen],len); + retstr[len] = '\0'; + } + } + } + } + } + + CERT_DestroyUserNotice(userNotice); + + return(retstr); +} + +char * +CERT_GetCertCommentString(CERTCertificate *cert) +{ + char *retstring = NULL; + SECStatus rv; + SECItem policyItem; + CERTCertificatePolicies *policies = NULL; + CERTPolicyInfo **policyInfos; + CERTPolicyQualifier **policyQualifiers, *qualifier; + + policyItem.data = NULL; + + rv = CERT_FindCertExtension(cert, SEC_OID_X509_CERTIFICATE_POLICIES, + &policyItem); + if ( rv != SECSuccess ) { + goto nopolicy; + } + + policies = CERT_DecodeCertificatePoliciesExtension(&policyItem); + if ( policies == NULL ) { + goto nopolicy; + } + + policyInfos = policies->policyInfos; + /* search through policyInfos looking for the verisign policy */ + while (*policyInfos != NULL ) { + if ( (*policyInfos)->oid == SEC_OID_VERISIGN_USER_NOTICES ) { + policyQualifiers = (*policyInfos)->policyQualifiers; + /* search through the policy qualifiers looking for user notice */ + while ( policyQualifiers != NULL && *policyQualifiers != NULL ) { + qualifier = *policyQualifiers; + if ( qualifier->oid == SEC_OID_PKIX_USER_NOTICE_QUALIFIER ) { + retstring = + stringFromUserNotice(&qualifier->qualifierValue); + break; + } + + policyQualifiers++; + } + break; + } + policyInfos++; + } + +nopolicy: + if ( policyItem.data != NULL ) { + PORT_Free(policyItem.data); + } + + if ( policies != NULL ) { + CERT_DestroyCertificatePoliciesExtension(policies); + } + + if ( retstring == NULL ) { + retstring = CERT_FindNSStringExtension(cert, + SEC_OID_NS_CERT_EXT_COMMENT); + } + + if ( retstring != NULL ) { + breakLines(retstring); + } + + return(retstring); +} + + +const SEC_ASN1Template CERT_OidSeqTemplate[] = { + { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, + offsetof(CERTOidSequence, oids), + SEC_ASN1_SUB(SEC_ObjectIDTemplate) } +}; + +CERTOidSequence * +CERT_DecodeOidSequence(const SECItem *seqItem) +{ + PLArenaPool *arena = NULL; + SECStatus rv; + CERTOidSequence *oidSeq; + SECItem newSeqItem; + + /* make a new arena */ + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + + if ( !arena ) { + goto loser; + } + + /* allocate the userNotice structure */ + oidSeq = (CERTOidSequence *)PORT_ArenaZAlloc(arena, + sizeof(CERTOidSequence)); + + if ( oidSeq == NULL ) { + goto loser; + } + + oidSeq->arena = arena; + + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newSeqItem, seqItem); + if ( rv != SECSuccess ) { + goto loser; + } + + /* decode the user notice */ + rv = SEC_QuickDERDecodeItem(arena, oidSeq, CERT_OidSeqTemplate, &newSeqItem); + + if ( rv != SECSuccess ) { + goto loser; + } + + return(oidSeq); + +loser: + if (arena) { + PORT_FreeArena(arena, PR_FALSE); + } + return(NULL); +} + + +void +CERT_DestroyOidSequence(CERTOidSequence *oidSeq) +{ + if ( oidSeq != NULL ) { + PORT_FreeArena(oidSeq->arena, PR_FALSE); + } + return; +} + +PRBool +CERT_GovtApprovedBitSet(CERTCertificate *cert) +{ + SECStatus rv; + SECItem extItem; + CERTOidSequence *oidSeq = NULL; + PRBool ret; + SECItem **oids; + SECItem *oid; + SECOidTag oidTag; + + extItem.data = NULL; + rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, &extItem); + if ( rv != SECSuccess ) { + goto loser; + } + + oidSeq = CERT_DecodeOidSequence(&extItem); + if ( oidSeq == NULL ) { + goto loser; + } + + oids = oidSeq->oids; + while ( oids != NULL && *oids != NULL ) { + oid = *oids; + + oidTag = SECOID_FindOIDTag(oid); + + if ( oidTag == SEC_OID_NS_KEY_USAGE_GOVT_APPROVED ) { + goto success; + } + + oids++; + } + +loser: + ret = PR_FALSE; + goto done; +success: + ret = PR_TRUE; +done: + if ( oidSeq != NULL ) { + CERT_DestroyOidSequence(oidSeq); + } + if (extItem.data != NULL) { + PORT_Free(extItem.data); + } + return(ret); +} + + +SECStatus +CERT_EncodePolicyConstraintsExtension(PLArenaPool *arena, + CERTCertificatePolicyConstraints *constr, + SECItem *dest) +{ + SECStatus rv = SECSuccess; + + PORT_Assert(constr != NULL && dest != NULL); + if (constr == NULL || dest == NULL) { + return SECFailure; + } + + if (SEC_ASN1EncodeItem (arena, dest, constr, + CERT_PolicyConstraintsTemplate) == NULL) { + rv = SECFailure; + } + return(rv); +} + +SECStatus +CERT_EncodePolicyMappingExtension(PLArenaPool *arena, + CERTCertificatePolicyMappings *mapping, + SECItem *dest) +{ + SECStatus rv = SECSuccess; + + PORT_Assert(mapping != NULL && dest != NULL); + if (mapping == NULL || dest == NULL) { + return SECFailure; + } + + if (SEC_ASN1EncodeItem (arena, dest, mapping, + CERT_PolicyMappingsTemplate) == NULL) { + rv = SECFailure; + } + return(rv); +} + + + +SECStatus +CERT_EncodeCertPoliciesExtension(PLArenaPool *arena, + CERTPolicyInfo **info, + SECItem *dest) +{ + SECStatus rv = SECSuccess; + + PORT_Assert(info != NULL && dest != NULL); + if (info == NULL || dest == NULL) { + return SECFailure; + } + + if (SEC_ASN1EncodeItem (arena, dest, info, + CERT_CertificatePoliciesTemplate) == NULL) { + rv = SECFailure; + } + return(rv); +} + +SECStatus +CERT_EncodeUserNotice(PLArenaPool *arena, + CERTUserNotice *notice, + SECItem *dest) +{ + SECStatus rv = SECSuccess; + + PORT_Assert(notice != NULL && dest != NULL); + if (notice == NULL || dest == NULL) { + return SECFailure; + } + + if (SEC_ASN1EncodeItem(arena, dest, + notice, CERT_UserNoticeTemplate) == NULL) { + rv = SECFailure; + } + + return(rv); +} + +SECStatus +CERT_EncodeNoticeReference(PLArenaPool *arena, + CERTNoticeReference *reference, + SECItem *dest) +{ + SECStatus rv = SECSuccess; + + PORT_Assert(reference != NULL && dest != NULL); + if (reference == NULL || dest == NULL) { + return SECFailure; + } + + if (SEC_ASN1EncodeItem (arena, dest, reference, + CERT_NoticeReferenceTemplate) == NULL) { + rv = SECFailure; + } + + return(rv); +} + +SECStatus +CERT_EncodeInhibitAnyExtension(PLArenaPool *arena, + CERTCertificateInhibitAny *certInhibitAny, + SECItem *dest) +{ + SECStatus rv = SECSuccess; + + PORT_Assert(certInhibitAny != NULL && dest != NULL); + if (certInhibitAny == NULL || dest == NULL) { + return SECFailure; + } + + if (SEC_ASN1EncodeItem (arena, dest, certInhibitAny, + CERT_InhibitAnyTemplate) == NULL) { + rv = SECFailure; + } + return(rv); +}