| /* 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); |
| } |