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);
+}
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)