security/nss/lib/certdb/polcyxtn.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * Support for various policy related extensions
     7  */
     9 #include "seccomon.h"
    10 #include "secport.h"
    11 #include "secder.h"
    12 #include "cert.h"
    13 #include "secoid.h"
    14 #include "secasn1.h"
    15 #include "secerr.h"
    16 #include "nspr.h"
    18 SEC_ASN1_MKSUB(SEC_IntegerTemplate)
    19 SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
    21 const SEC_ASN1Template CERT_DisplayTextTypeTemplate[] = {
    22     { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) },
    23     { SEC_ASN1_IA5_STRING, 0, 0, siAsciiString},
    24     { SEC_ASN1_VISIBLE_STRING , 0, 0, siVisibleString},
    25     { SEC_ASN1_BMP_STRING  , 0, 0, siBMPString },
    26     { SEC_ASN1_UTF8_STRING , 0, 0, siUTF8String },
    27     { 0 }
    28 };
    30 const SEC_ASN1Template CERT_NoticeReferenceTemplate[] = {
    31     { SEC_ASN1_SEQUENCE,
    32 	  0, NULL, sizeof(CERTNoticeReference) },
    33     { SEC_ASN1_INLINE,
    34 	  offsetof(CERTNoticeReference, organization),
    35            CERT_DisplayTextTypeTemplate, 0 },
    36     { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN,
    37            offsetof(CERTNoticeReference, noticeNumbers),
    38            SEC_ASN1_SUB(SEC_IntegerTemplate) }, 
    39     { 0 }
    40 };
    42 const SEC_ASN1Template CERT_UserNoticeTemplate[] = {
    43     { SEC_ASN1_SEQUENCE,
    44 	  0, NULL, sizeof(CERTUserNotice) },
    45     { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL,
    46 	  offsetof(CERTUserNotice, noticeReference),
    47            CERT_NoticeReferenceTemplate, 0 },
    48     { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL,
    49 	  offsetof(CERTUserNotice, displayText),
    50            CERT_DisplayTextTypeTemplate, 0 }, 
    51     { 0 }
    52 };
    54 const SEC_ASN1Template CERT_PolicyQualifierTemplate[] = {
    55     { SEC_ASN1_SEQUENCE,
    56 	  0, NULL, sizeof(CERTPolicyQualifier) },
    57     { SEC_ASN1_OBJECT_ID,
    58 	  offsetof(CERTPolicyQualifier, qualifierID) },
    59     { SEC_ASN1_ANY,
    60 	  offsetof(CERTPolicyQualifier, qualifierValue) },
    61     { 0 }
    62 };
    64 const SEC_ASN1Template CERT_PolicyInfoTemplate[] = {
    65     { SEC_ASN1_SEQUENCE,
    66 	  0, NULL, sizeof(CERTPolicyInfo) },
    67     { SEC_ASN1_OBJECT_ID,
    68 	  offsetof(CERTPolicyInfo, policyID) },
    69     { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_OPTIONAL,
    70 	  offsetof(CERTPolicyInfo, policyQualifiers),
    71 	  CERT_PolicyQualifierTemplate },
    72     { 0 }
    73 };
    75 const SEC_ASN1Template CERT_CertificatePoliciesTemplate[] = {
    76     { SEC_ASN1_SEQUENCE_OF,
    77 	  offsetof(CERTCertificatePolicies, policyInfos),
    78 	  CERT_PolicyInfoTemplate, sizeof(CERTCertificatePolicies)  }
    79 };
    81 const SEC_ASN1Template CERT_PolicyMapTemplate[] = {
    82     { SEC_ASN1_SEQUENCE,
    83 	  0, NULL, sizeof(CERTPolicyMap) },
    84     { SEC_ASN1_OBJECT_ID,
    85 	  offsetof(CERTPolicyMap, issuerDomainPolicy) },
    86     { SEC_ASN1_OBJECT_ID,
    87 	  offsetof(CERTPolicyMap, subjectDomainPolicy) },
    88     { 0 }
    89 };
    91 const SEC_ASN1Template CERT_PolicyMappingsTemplate[] = {
    92     { SEC_ASN1_SEQUENCE_OF,
    93 	  offsetof(CERTCertificatePolicyMappings, policyMaps),
    94 	  CERT_PolicyMapTemplate, sizeof(CERTPolicyMap)  }
    95 };
    97 const SEC_ASN1Template CERT_PolicyConstraintsTemplate[] = {
    98     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCertificatePolicyConstraints) },
    99     { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
   100 	  offsetof(CERTCertificatePolicyConstraints, explicitPolicySkipCerts),
   101 	  SEC_ASN1_SUB(SEC_IntegerTemplate) },
   102     { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
   103 	  offsetof(CERTCertificatePolicyConstraints, inhibitMappingSkipCerts),
   104 	  SEC_ASN1_SUB(SEC_IntegerTemplate) },
   105     { 0 }
   106 };
   108 const SEC_ASN1Template CERT_InhibitAnyTemplate[] = {
   109     { SEC_ASN1_INTEGER,
   110 	  offsetof(CERTCertificateInhibitAny, inhibitAnySkipCerts),
   111 	  NULL, sizeof(CERTCertificateInhibitAny)  }
   112 };
   114 static void
   115 breakLines(char *string)
   116 {
   117     char *tmpstr;
   118     char *lastspace = NULL;
   119     int curlen = 0;
   120     int c;
   122     tmpstr = string;
   124     while ( ( c = *tmpstr ) != '\0' ) {
   125 	switch ( c ) {
   126 	  case ' ':
   127 	    lastspace = tmpstr;
   128 	    break;
   129 	  case '\n':
   130 	    lastspace = NULL;
   131 	    curlen = 0;
   132 	    break;
   133 	}
   135 	if ( ( curlen >= 55 ) && ( lastspace != NULL ) ) {
   136 	    *lastspace = '\n';
   137 	    curlen = ( tmpstr - lastspace );
   138 	    lastspace = NULL;
   139 	}
   141 	curlen++;
   142 	tmpstr++;
   143     }
   145     return;
   146 }
   148 CERTCertificatePolicies *
   149 CERT_DecodeCertificatePoliciesExtension(const SECItem *extnValue)
   150 {
   151     PLArenaPool *arena = NULL;
   152     SECStatus rv;
   153     CERTCertificatePolicies *policies;
   154     CERTPolicyInfo **policyInfos, *policyInfo;
   155     CERTPolicyQualifier **policyQualifiers, *policyQualifier;
   156     SECItem newExtnValue;
   158     /* make a new arena */
   159     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
   161     if ( !arena ) {
   162 	goto loser;
   163     }
   165     /* allocate the certificate policies structure */
   166     policies = (CERTCertificatePolicies *)
   167 	PORT_ArenaZAlloc(arena, sizeof(CERTCertificatePolicies));
   169     if ( policies == NULL ) {
   170 	goto loser;
   171     }
   173     policies->arena = arena;
   175     /* copy the DER into the arena, since Quick DER returns data that points
   176        into the DER input, which may get freed by the caller */
   177     rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
   178     if ( rv != SECSuccess ) {
   179 	goto loser;
   180     }
   182     /* decode the policy info */
   183     rv = SEC_QuickDERDecodeItem(arena, policies, CERT_CertificatePoliciesTemplate,
   184 			    &newExtnValue);
   186     if ( rv != SECSuccess ) {
   187 	goto loser;
   188     }
   190     /* initialize the oid tags */
   191     policyInfos = policies->policyInfos;
   192     while (*policyInfos != NULL ) {
   193 	policyInfo = *policyInfos;
   194 	policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID);
   195 	policyQualifiers = policyInfo->policyQualifiers;
   196 	while ( policyQualifiers != NULL && *policyQualifiers != NULL ) {
   197 	    policyQualifier = *policyQualifiers;
   198 	    policyQualifier->oid =
   199 		SECOID_FindOIDTag(&policyQualifier->qualifierID);
   200 	    policyQualifiers++;
   201 	}
   202 	policyInfos++;
   203     }
   205     return(policies);
   207 loser:
   208     if ( arena != NULL ) {
   209 	PORT_FreeArena(arena, PR_FALSE);
   210     }
   212     return(NULL);
   213 }
   215 void
   216 CERT_DestroyCertificatePoliciesExtension(CERTCertificatePolicies *policies)
   217 {
   218     if ( policies != NULL ) {
   219 	PORT_FreeArena(policies->arena, PR_FALSE);
   220     }
   221     return;
   222 }
   224 CERTCertificatePolicyMappings *
   225 CERT_DecodePolicyMappingsExtension(SECItem *extnValue)
   226 {
   227     PLArenaPool *arena = NULL;
   228     SECStatus rv;
   229     CERTCertificatePolicyMappings *mappings;
   230     SECItem newExtnValue;
   232     /* make a new arena */
   233     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
   234     if ( !arena ) {
   235         goto loser;
   236     }
   238     /* allocate the policy mappings structure */
   239     mappings = (CERTCertificatePolicyMappings *)
   240         PORT_ArenaZAlloc(arena, sizeof(CERTCertificatePolicyMappings));
   241     if ( mappings == NULL ) {
   242         goto loser;
   243     }
   244     mappings->arena = arena;
   246     /* copy the DER into the arena, since Quick DER returns data that points
   247        into the DER input, which may get freed by the caller */
   248     rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
   249     if ( rv != SECSuccess ) {
   250         goto loser;
   251     }
   253     /* decode the policy mappings */
   254     rv = SEC_QuickDERDecodeItem
   255         (arena, mappings, CERT_PolicyMappingsTemplate, &newExtnValue);
   256     if ( rv != SECSuccess ) {
   257         goto loser;
   258     }
   260     return(mappings);
   262 loser:
   263     if ( arena != NULL ) {
   264         PORT_FreeArena(arena, PR_FALSE);
   265     }
   267     return(NULL);
   268 }
   270 SECStatus
   271 CERT_DestroyPolicyMappingsExtension(CERTCertificatePolicyMappings *mappings)
   272 {
   273     if ( mappings != NULL ) {
   274         PORT_FreeArena(mappings->arena, PR_FALSE);
   275     }
   276     return SECSuccess;
   277 }
   279 SECStatus
   280 CERT_DecodePolicyConstraintsExtension
   281                              (CERTCertificatePolicyConstraints *decodedValue,
   282                               const SECItem *encodedValue)
   283 {
   284     CERTCertificatePolicyConstraints decodeContext;
   285     PLArenaPool *arena = NULL;
   286     SECStatus rv = SECSuccess;
   288     /* initialize so we can tell when an optional component is omitted */
   289     PORT_Memset(&decodeContext, 0, sizeof(decodeContext));
   291     /* make a new arena */
   292     arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
   293     if (!arena) {
   294         return SECFailure;
   295     }
   297     do {
   298         /* decode the policy constraints */
   299         rv = SEC_QuickDERDecodeItem(arena,
   300                 &decodeContext, CERT_PolicyConstraintsTemplate, encodedValue);
   302         if ( rv != SECSuccess ) {
   303             break;
   304         }
   306         if (decodeContext.explicitPolicySkipCerts.len == 0) {
   307             *(PRInt32 *)decodedValue->explicitPolicySkipCerts.data = -1;
   308         } else {
   309             *(PRInt32 *)decodedValue->explicitPolicySkipCerts.data =
   310                     DER_GetInteger(&decodeContext.explicitPolicySkipCerts);
   311         }
   313         if (decodeContext.inhibitMappingSkipCerts.len == 0) {
   314             *(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data = -1;
   315         } else {
   316             *(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data =
   317                     DER_GetInteger(&decodeContext.inhibitMappingSkipCerts);
   318         }
   320         if ((*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data ==
   321                 PR_INT32_MIN) ||
   322             (*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data ==
   323                 PR_INT32_MAX) ||
   324             (*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data ==
   325                 PR_INT32_MIN) ||
   326             (*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data ==
   327                 PR_INT32_MAX)) {
   328             rv = SECFailure;
   329         }
   331     } while (0);
   333     PORT_FreeArena(arena, PR_FALSE);
   334     return(rv);
   335 }
   337 SECStatus CERT_DecodeInhibitAnyExtension
   338         (CERTCertificateInhibitAny *decodedValue, SECItem *encodedValue)
   339 {
   340     CERTCertificateInhibitAny decodeContext;
   341     PLArenaPool *arena = NULL;
   342     SECStatus rv = SECSuccess;
   344     /* make a new arena */
   345     arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
   346     if ( !arena ) {
   347         return SECFailure;
   348     }
   350     do {
   352         /* decode the policy mappings */
   353         decodeContext.inhibitAnySkipCerts.type = siUnsignedInteger;
   354         rv = SEC_QuickDERDecodeItem(arena,
   355                 &decodeContext, CERT_InhibitAnyTemplate, encodedValue);
   357         if ( rv != SECSuccess ) {
   358             break;
   359         }
   361         *(PRInt32 *)decodedValue->inhibitAnySkipCerts.data =
   362                 DER_GetInteger(&decodeContext.inhibitAnySkipCerts);
   364     } while (0);
   366     PORT_FreeArena(arena, PR_FALSE);
   367     return(rv);
   368 }
   370 CERTUserNotice *
   371 CERT_DecodeUserNotice(SECItem *noticeItem)
   372 {
   373     PLArenaPool *arena = NULL;
   374     SECStatus rv;
   375     CERTUserNotice *userNotice;
   376     SECItem newNoticeItem;
   378     /* make a new arena */
   379     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
   381     if ( !arena ) {
   382 	goto loser;
   383     }
   385     /* allocate the userNotice structure */
   386     userNotice = (CERTUserNotice *)PORT_ArenaZAlloc(arena,
   387 						    sizeof(CERTUserNotice));
   389     if ( userNotice == NULL ) {
   390 	goto loser;
   391     }
   393     userNotice->arena = arena;
   395     /* copy the DER into the arena, since Quick DER returns data that points
   396        into the DER input, which may get freed by the caller */
   397     rv = SECITEM_CopyItem(arena, &newNoticeItem, noticeItem);
   398     if ( rv != SECSuccess ) {
   399 	goto loser;
   400     }
   402     /* decode the user notice */
   403     rv = SEC_QuickDERDecodeItem(arena, userNotice, CERT_UserNoticeTemplate, 
   404 			    &newNoticeItem);
   406     if ( rv != SECSuccess ) {
   407 	goto loser;
   408     }
   410     if (userNotice->derNoticeReference.data != NULL) {
   412         rv = SEC_QuickDERDecodeItem(arena, &userNotice->noticeReference,
   413                                     CERT_NoticeReferenceTemplate,
   414                                     &userNotice->derNoticeReference);
   415         if (rv == SECFailure) {
   416             goto loser;
   417     	}
   418     }
   420     return(userNotice);
   422 loser:
   423     if ( arena != NULL ) {
   424 	PORT_FreeArena(arena, PR_FALSE);
   425     }
   427     return(NULL);
   428 }
   430 void
   431 CERT_DestroyUserNotice(CERTUserNotice *userNotice)
   432 {
   433     if ( userNotice != NULL ) {
   434 	PORT_FreeArena(userNotice->arena, PR_FALSE);
   435     }
   436     return;
   437 }
   439 static CERTPolicyStringCallback policyStringCB = NULL;
   440 static void *policyStringCBArg = NULL;
   442 void
   443 CERT_SetCAPolicyStringCallback(CERTPolicyStringCallback cb, void *cbarg)
   444 {
   445     policyStringCB = cb;
   446     policyStringCBArg = cbarg;
   447     return;
   448 }
   450 char *
   451 stringFromUserNotice(SECItem *noticeItem)
   452 {
   453     SECItem *org;
   454     unsigned int len, headerlen;
   455     char *stringbuf;
   456     CERTUserNotice *userNotice;
   457     char *policystr;
   458     char *retstr = NULL;
   459     SECItem *displayText;
   460     SECItem **noticeNumbers;
   461     unsigned int strnum;
   463     /* decode the user notice */
   464     userNotice = CERT_DecodeUserNotice(noticeItem);
   465     if ( userNotice == NULL ) {
   466 	return(NULL);
   467     }
   469     org = &userNotice->noticeReference.organization;
   470     if ( (org->len != 0 ) && ( policyStringCB != NULL ) ) {
   471 	/* has a noticeReference */
   473 	/* extract the org string */
   474 	len = org->len;
   475 	stringbuf = (char*)PORT_Alloc(len + 1);
   476 	if ( stringbuf != NULL ) {
   477 	    PORT_Memcpy(stringbuf, org->data, len);
   478 	    stringbuf[len] = '\0';
   480 	    noticeNumbers = userNotice->noticeReference.noticeNumbers;
   481 	    while ( *noticeNumbers != NULL ) {
   482 		/* XXX - only one byte integers right now*/
   483 		strnum = (*noticeNumbers)->data[0];
   484 		policystr = (* policyStringCB)(stringbuf,
   485 					       strnum,
   486 					       policyStringCBArg);
   487 		if ( policystr != NULL ) {
   488 		    if ( retstr != NULL ) {
   489 			retstr = PR_sprintf_append(retstr, "\n%s", policystr);
   490 		    } else {
   491 			retstr = PR_sprintf_append(retstr, "%s", policystr);
   492 		    }
   494 		    PORT_Free(policystr);
   495 		}
   497 		noticeNumbers++;
   498 	    }
   500 	    PORT_Free(stringbuf);
   501 	}
   502     }
   504     if ( retstr == NULL ) {
   505 	if ( userNotice->displayText.len != 0 ) {
   506 	    displayText = &userNotice->displayText;
   508 	    if ( displayText->len > 2 ) {
   509 		if ( displayText->data[0] == SEC_ASN1_VISIBLE_STRING ) {
   510 		    headerlen = 2;
   511 		    if ( displayText->data[1] & 0x80 ) {
   512 			/* multibyte length */
   513 			headerlen += ( displayText->data[1] & 0x7f );
   514 		    }
   516 		    len = displayText->len - headerlen;
   517 		    retstr = (char*)PORT_Alloc(len + 1);
   518 		    if ( retstr != NULL ) {
   519 			PORT_Memcpy(retstr, &displayText->data[headerlen],len);
   520 			retstr[len] = '\0';
   521 		    }
   522 		}
   523 	    }
   524 	}
   525     }
   527     CERT_DestroyUserNotice(userNotice);
   529     return(retstr);
   530 }
   532 char *
   533 CERT_GetCertCommentString(CERTCertificate *cert)
   534 {
   535     char *retstring = NULL;
   536     SECStatus rv;
   537     SECItem policyItem;
   538     CERTCertificatePolicies *policies = NULL;
   539     CERTPolicyInfo **policyInfos;
   540     CERTPolicyQualifier **policyQualifiers, *qualifier;
   542     policyItem.data = NULL;
   544     rv = CERT_FindCertExtension(cert, SEC_OID_X509_CERTIFICATE_POLICIES,
   545 				&policyItem);
   546     if ( rv != SECSuccess ) {
   547 	goto nopolicy;
   548     }
   550     policies = CERT_DecodeCertificatePoliciesExtension(&policyItem);
   551     if ( policies == NULL ) {
   552 	goto nopolicy;
   553     }
   555     policyInfos = policies->policyInfos;
   556     /* search through policyInfos looking for the verisign policy */
   557     while (*policyInfos != NULL ) {
   558 	if ( (*policyInfos)->oid == SEC_OID_VERISIGN_USER_NOTICES ) {
   559 	    policyQualifiers = (*policyInfos)->policyQualifiers;
   560 	    /* search through the policy qualifiers looking for user notice */
   561 	    while ( policyQualifiers != NULL && *policyQualifiers != NULL ) {
   562 		qualifier = *policyQualifiers;
   563 		if ( qualifier->oid == SEC_OID_PKIX_USER_NOTICE_QUALIFIER ) {
   564 		    retstring =
   565 			stringFromUserNotice(&qualifier->qualifierValue);
   566 		    break;
   567 		}
   569 		policyQualifiers++;
   570 	    }
   571 	    break;
   572 	}
   573 	policyInfos++;
   574     }
   576 nopolicy:
   577     if ( policyItem.data != NULL ) {
   578 	PORT_Free(policyItem.data);
   579     }
   581     if ( policies != NULL ) {
   582 	CERT_DestroyCertificatePoliciesExtension(policies);
   583     }
   585     if ( retstring == NULL ) {
   586 	retstring = CERT_FindNSStringExtension(cert,
   587 					       SEC_OID_NS_CERT_EXT_COMMENT);
   588     }
   590     if ( retstring != NULL ) {
   591 	breakLines(retstring);
   592     }
   594     return(retstring);
   595 }
   598 const SEC_ASN1Template CERT_OidSeqTemplate[] = {
   599     { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN,
   600 	  offsetof(CERTOidSequence, oids),
   601 	  SEC_ASN1_SUB(SEC_ObjectIDTemplate) }
   602 };
   604 CERTOidSequence *
   605 CERT_DecodeOidSequence(const SECItem *seqItem)
   606 {
   607     PLArenaPool *arena = NULL;
   608     SECStatus rv;
   609     CERTOidSequence *oidSeq;
   610     SECItem newSeqItem;
   612     /* make a new arena */
   613     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
   615     if ( !arena ) {
   616 	goto loser;
   617     }
   619     /* allocate the userNotice structure */
   620     oidSeq = (CERTOidSequence *)PORT_ArenaZAlloc(arena,
   621 						 sizeof(CERTOidSequence));
   623     if ( oidSeq == NULL ) {
   624 	goto loser;
   625     }
   627     oidSeq->arena = arena;
   629     /* copy the DER into the arena, since Quick DER returns data that points
   630        into the DER input, which may get freed by the caller */
   631     rv = SECITEM_CopyItem(arena, &newSeqItem, seqItem);
   632     if ( rv != SECSuccess ) {
   633 	goto loser;
   634     }
   636     /* decode the user notice */
   637     rv = SEC_QuickDERDecodeItem(arena, oidSeq, CERT_OidSeqTemplate, &newSeqItem);
   639     if ( rv != SECSuccess ) {
   640 	goto loser;
   641     }
   643     return(oidSeq);
   645 loser:
   646     if (arena) {
   647         PORT_FreeArena(arena, PR_FALSE);
   648     }
   649     return(NULL);
   650 }
   653 void
   654 CERT_DestroyOidSequence(CERTOidSequence *oidSeq)
   655 {
   656     if ( oidSeq != NULL ) {
   657 	PORT_FreeArena(oidSeq->arena, PR_FALSE);
   658     }
   659     return;
   660 }
   662 PRBool
   663 CERT_GovtApprovedBitSet(CERTCertificate *cert)
   664 {
   665     SECStatus rv;
   666     SECItem extItem;
   667     CERTOidSequence *oidSeq = NULL;
   668     PRBool ret;
   669     SECItem **oids;
   670     SECItem *oid;
   671     SECOidTag oidTag;
   673     extItem.data = NULL;
   674     rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, &extItem);
   675     if ( rv != SECSuccess ) {
   676 	goto loser;
   677     }
   679     oidSeq = CERT_DecodeOidSequence(&extItem);
   680     if ( oidSeq == NULL ) {
   681 	goto loser;
   682     }
   684     oids = oidSeq->oids;
   685     while ( oids != NULL && *oids != NULL ) {
   686 	oid = *oids;
   688 	oidTag = SECOID_FindOIDTag(oid);
   690 	if ( oidTag == SEC_OID_NS_KEY_USAGE_GOVT_APPROVED ) {
   691 	    goto success;
   692 	}
   694 	oids++;
   695     }
   697 loser:
   698     ret = PR_FALSE;
   699     goto done;
   700 success:
   701     ret = PR_TRUE;
   702 done:
   703     if ( oidSeq != NULL ) {
   704 	CERT_DestroyOidSequence(oidSeq);
   705     }
   706     if (extItem.data != NULL) {
   707 	PORT_Free(extItem.data);
   708     }
   709     return(ret);
   710 }
   713 SECStatus
   714 CERT_EncodePolicyConstraintsExtension(PLArenaPool *arena,
   715                                       CERTCertificatePolicyConstraints *constr,
   716                                       SECItem *dest)
   717 {
   718     SECStatus rv = SECSuccess;
   720     PORT_Assert(constr != NULL && dest != NULL);
   721     if (constr == NULL || dest == NULL) {
   722 	return SECFailure;
   723     }
   725     if (SEC_ASN1EncodeItem (arena, dest, constr,
   726                             CERT_PolicyConstraintsTemplate) == NULL) {
   727 	rv = SECFailure;
   728     }
   729     return(rv);
   730 }
   732 SECStatus
   733 CERT_EncodePolicyMappingExtension(PLArenaPool *arena,
   734                                   CERTCertificatePolicyMappings *mapping,
   735                                   SECItem *dest)
   736 {
   737     SECStatus rv = SECSuccess;
   739     PORT_Assert(mapping != NULL && dest != NULL);
   740     if (mapping == NULL || dest == NULL) {
   741 	return SECFailure;
   742     }
   744     if (SEC_ASN1EncodeItem (arena, dest, mapping,
   745                             CERT_PolicyMappingsTemplate) == NULL) {
   746 	rv = SECFailure;
   747     }
   748     return(rv);
   749 }
   753 SECStatus
   754 CERT_EncodeCertPoliciesExtension(PLArenaPool *arena,
   755                                  CERTPolicyInfo **info,
   756                                  SECItem *dest)
   757 {
   758     SECStatus rv = SECSuccess;
   760     PORT_Assert(info != NULL && dest != NULL);
   761     if (info == NULL || dest == NULL) {
   762 	return SECFailure;
   763     }
   765     if (SEC_ASN1EncodeItem (arena, dest, info,
   766                             CERT_CertificatePoliciesTemplate) == NULL) {
   767 	rv = SECFailure;
   768     }
   769     return(rv);
   770 }
   772 SECStatus
   773 CERT_EncodeUserNotice(PLArenaPool *arena,
   774                       CERTUserNotice *notice,
   775                       SECItem *dest)
   776 {
   777     SECStatus rv = SECSuccess;
   779     PORT_Assert(notice != NULL && dest != NULL);
   780     if (notice == NULL || dest == NULL) {
   781 	return SECFailure;
   782     }
   784     if (SEC_ASN1EncodeItem(arena, dest,
   785                            notice, CERT_UserNoticeTemplate) == NULL) {
   786 	rv = SECFailure;
   787     }
   789     return(rv);
   790 }
   792 SECStatus
   793 CERT_EncodeNoticeReference(PLArenaPool *arena,
   794                            CERTNoticeReference *reference,
   795                            SECItem *dest)
   796 {
   797     SECStatus rv = SECSuccess;
   799     PORT_Assert(reference != NULL && dest != NULL);
   800     if (reference == NULL || dest == NULL) {
   801 	return SECFailure;
   802     }
   804     if (SEC_ASN1EncodeItem (arena, dest, reference,
   805                             CERT_NoticeReferenceTemplate) == NULL) {
   806 	rv = SECFailure;
   807     }
   809     return(rv);
   810 }
   812 SECStatus
   813 CERT_EncodeInhibitAnyExtension(PLArenaPool *arena,
   814                                CERTCertificateInhibitAny *certInhibitAny,
   815                                SECItem *dest)
   816 {
   817     SECStatus rv = SECSuccess;
   819     PORT_Assert(certInhibitAny != NULL && dest != NULL);
   820     if (certInhibitAny == NULL || dest == NULL) {
   821 	return SECFailure;
   822     }
   824     if (SEC_ASN1EncodeItem (arena, dest, certInhibitAny,
   825                             CERT_InhibitAnyTemplate) == NULL) {
   826 	rv = SECFailure;
   827     }
   828     return(rv);
   829 }

mercurial