genname.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,611 行 · 第 1/3 页
C
1,611 行
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape security libraries. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "plarena.h"#include "seccomon.h"#include "secitem.h"#include "secoidt.h"#include "mcom_db.h"#include "secasn1.h"#include "secder.h"#include "certt.h"#include "cert.h"#include "xconst.h"#include "secerr.h"#include "secoid.h"#include "prprf.h"#include "genname.h"static const SEC_ASN1Template CERTNameConstraintTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraint) }, { SEC_ASN1_ANY, offsetof(CERTNameConstraint, DERName) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(CERTNameConstraint, min), SEC_IntegerTemplate }, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1, offsetof(CERTNameConstraint, max), SEC_IntegerTemplate }, { 0, }};const SEC_ASN1Template CERT_NameConstraintSubtreeSubTemplate[] = { { SEC_ASN1_SEQUENCE_OF, 0, SEC_AnyTemplate }};const SEC_ASN1Template CERT_NameConstraintSubtreePermitedTemplate[] = { { SEC_ASN1_CONTEXT_SPECIFIC | 0, 0, CERT_NameConstraintSubtreeSubTemplate }};const SEC_ASN1Template CERT_NameConstraintSubtreeExcludedTemplate[] = { { SEC_ASN1_CONTEXT_SPECIFIC | 1, 0, CERT_NameConstraintSubtreeSubTemplate }};static const SEC_ASN1Template CERTNameConstraintsTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraints) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(CERTNameConstraints, DERPermited), CERT_NameConstraintSubtreeSubTemplate}, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1, offsetof(CERTNameConstraints, DERExcluded), CERT_NameConstraintSubtreeSubTemplate}, { 0, }};static const SEC_ASN1Template CERTOthNameTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(OtherName) }, { SEC_ASN1_OBJECT_ID, offsetof(OtherName, oid) }, { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 0, offsetof(OtherName, name), SEC_AnyTemplate }, { 0, } };static const SEC_ASN1Template CERTOtherNameTemplate[] = { { SEC_ASN1_CONTEXT_SPECIFIC | 0 , offsetof(CERTGeneralName, name.OthName), CERTOthNameTemplate, sizeof(CERTGeneralName) }};static const SEC_ASN1Template CERTOtherName2Template[] = { { SEC_ASN1_SEQUENCE | SEC_ASN1_CONTEXT_SPECIFIC | 0 , 0, NULL, sizeof(CERTGeneralName) }, { SEC_ASN1_OBJECT_ID, offsetof(CERTGeneralName, name.OthName) + offsetof(OtherName, oid) }, { SEC_ASN1_ANY, offsetof(CERTGeneralName, name.OthName) + offsetof(OtherName, name) }, { 0, } };static const SEC_ASN1Template CERT_RFC822NameTemplate[] = { { SEC_ASN1_CONTEXT_SPECIFIC | 1 , offsetof(CERTGeneralName, name.other), SEC_IA5StringTemplate, sizeof (CERTGeneralName)}};static const SEC_ASN1Template CERT_DNSNameTemplate[] = { { SEC_ASN1_CONTEXT_SPECIFIC | 2 , offsetof(CERTGeneralName, name.other), SEC_IA5StringTemplate, sizeof (CERTGeneralName)}};static const SEC_ASN1Template CERT_X400AddressTemplate[] = { { SEC_ASN1_ANY | SEC_ASN1_CONTEXT_SPECIFIC | 3, offsetof(CERTGeneralName, name.other), SEC_AnyTemplate, sizeof (CERTGeneralName)}};static const SEC_ASN1Template CERT_DirectoryNameTemplate[] = { { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 4, offsetof(CERTGeneralName, derDirectoryName), SEC_AnyTemplate, sizeof (CERTGeneralName)}};static const SEC_ASN1Template CERT_EDIPartyNameTemplate[] = { { SEC_ASN1_ANY | SEC_ASN1_CONTEXT_SPECIFIC | 5, offsetof(CERTGeneralName, name.other), SEC_AnyTemplate, sizeof (CERTGeneralName)}};static const SEC_ASN1Template CERT_URITemplate[] = { { SEC_ASN1_CONTEXT_SPECIFIC | 6 , offsetof(CERTGeneralName, name.other), SEC_IA5StringTemplate, sizeof (CERTGeneralName)}};static const SEC_ASN1Template CERT_IPAddressTemplate[] = { { SEC_ASN1_CONTEXT_SPECIFIC | 7 , offsetof(CERTGeneralName, name.other), SEC_OctetStringTemplate, sizeof (CERTGeneralName)}};static const SEC_ASN1Template CERT_RegisteredIDTemplate[] = { { SEC_ASN1_CONTEXT_SPECIFIC | 8 , offsetof(CERTGeneralName, name.other), SEC_ObjectIDTemplate, sizeof (CERTGeneralName)}};const SEC_ASN1Template CERT_GeneralNamesTemplate[] = { { SEC_ASN1_SEQUENCE_OF, 0, SEC_AnyTemplate }};voidCERT_DestroyGeneralNameList(CERTGeneralNameList *list){ PRLock *lock; if (list != NULL) { lock = list->lock; PR_Lock(lock); if (--list->refCount <= 0 && list->arena != NULL) { PORT_FreeArena(list->arena, PR_FALSE); PR_Unlock(lock); PR_DestroyLock(lock); } else { PR_Unlock(lock); } } return;}CERTGeneralNameList *CERT_CreateGeneralNameList(CERTGeneralName *name) { PRArenaPool *arena; CERTGeneralNameList *list = NULL; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { goto done; } list = (CERTGeneralNameList *) PORT_ArenaZAlloc(arena, sizeof(CERTGeneralNameList)); if (name != NULL) { list->name = (CERTGeneralName *) PORT_ArenaZAlloc(arena, sizeof(CERTGeneralName)); list->name->l.next = list->name->l.prev = &list->name->l; CERT_CopyGeneralName(arena, list->name, name); } list->lock = PR_NewLock(); list->arena = arena; list->refCount = 1;done: return list;}CERTGeneralName *cert_get_next_general_name(CERTGeneralName *current){ PRCList *next; next = current->l.next; return (CERTGeneralName *) (((char *) next) - offsetof(CERTGeneralName, l));}CERTGeneralName *cert_get_prev_general_name(CERTGeneralName *current){ PRCList *prev; prev = current->l.prev; return (CERTGeneralName *) (((char *) prev) - offsetof(CERTGeneralName, l));}CERTNameConstraint *cert_get_next_name_constraint(CERTNameConstraint *current){ PRCList *next; next = current->l.next; return (CERTNameConstraint *) (((char *) next) - offsetof(CERTNameConstraint, l));}CERTNameConstraint *cert_get_prev_name_constraint(CERTNameConstraint *current){ PRCList *prev; prev = current->l.prev; return (CERTNameConstraint *) (((char *) prev) - offsetof(CERTNameConstraint, l));}SECItem *cert_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest, PRArenaPool *arena){ PORT_Assert(arena); if (arena == NULL) { goto loser; } if (dest == NULL) { dest = (SECItem *) PORT_ArenaZAlloc(arena, sizeof(SECItem)); } switch (genName->type) { case certURI: dest = SEC_ASN1EncodeItem(arena, dest, genName, CERT_URITemplate); break; case certRFC822Name: dest = SEC_ASN1EncodeItem(arena, dest, genName, CERT_RFC822NameTemplate); break; case certDNSName: dest = SEC_ASN1EncodeItem(arena, dest, genName, CERT_DNSNameTemplate); break; case certIPAddress: dest = SEC_ASN1EncodeItem(arena, dest, genName, CERT_IPAddressTemplate); break; case certOtherName: dest = SEC_ASN1EncodeItem(arena, dest, genName, CERTOtherNameTemplate); break; case certRegisterID: dest = SEC_ASN1EncodeItem(arena, dest, genName, CERT_RegisteredIDTemplate); break; case certEDIPartyName: /* for this type, we expect the value is already encoded */ dest = SEC_ASN1EncodeItem (arena, dest, genName, CERT_EDIPartyNameTemplate); break; case certX400Address: /* for this type, we expect the value is already encoded */ dest = SEC_ASN1EncodeItem (arena, dest, genName, CERT_X400AddressTemplate); break; case certDirectoryName: if (genName->derDirectoryName.data == NULL) { /* The field hasn't been encoded yet. */ SEC_ASN1EncodeItem (arena, &(genName->derDirectoryName), &(genName->name.directoryName), CERT_NameTemplate); } if (genName->derDirectoryName.data == NULL) { goto loser; } dest = SEC_ASN1EncodeItem(arena, dest, genName, CERT_DirectoryNameTemplate); break; } if (!dest) { goto loser; } return dest;loser: return NULL;}SECItem **cert_EncodeGeneralNames(PRArenaPool *arena, CERTGeneralName *names){ CERTGeneralName *current_name; SECItem **items = NULL; int count = 0; int i; PRCList *head; PORT_Assert(arena); current_name = names; if (names != NULL) { count = 1; } head = &(names->l); while (current_name->l.next != head) { current_name = cert_get_next_general_name(current_name); ++count; } current_name = cert_get_next_general_name(current_name); items = (SECItem **) PORT_ArenaAlloc(arena, sizeof(SECItem *) * (count + 1)); if (items == NULL) { goto loser; } for (i = 0; i < count; i++) { items[i] = cert_EncodeGeneralName(current_name, (SECItem *) NULL, arena); if (items[i] == NULL) { goto loser; } current_name = cert_get_next_general_name(current_name); } items[i] = NULL; return items;loser: return NULL;}CERTGeneralName *cert_DecodeGeneralName(PRArenaPool *arena, SECItem *encodedName, CERTGeneralName *genName){ CERTGeneralNameType genNameType; SECStatus rv = SECSuccess; PORT_Assert(arena); if (genName == NULL) { genName = (CERTGeneralName *) PORT_ArenaZAlloc(arena, sizeof(CERTGeneralName)); } genNameType = (CERTGeneralNameType)((*(encodedName->data) & 0x0f) + 1); switch (genNameType) { case certURI: rv = SEC_ASN1DecodeItem(arena, genName, CERT_URITemplate, encodedName); break; case certRFC822Name: rv = SEC_ASN1DecodeItem(arena, genName, CERT_RFC822NameTemplate, encodedName); break; case certDNSName: rv = SEC_ASN1DecodeItem(arena, genName, CERT_DNSNameTemplate, encodedName); break; case certIPAddress: rv = SEC_ASN1DecodeItem(arena, genName, CERT_IPAddressTemplate, encodedName); break; case certOtherName: rv = SEC_ASN1DecodeItem(arena, genName, CERTOtherNameTemplate, encodedName); break; case certRegisterID: rv = SEC_ASN1DecodeItem(arena, genName, CERT_RegisteredIDTemplate, encodedName); break; case certEDIPartyName: rv = SEC_ASN1DecodeItem(arena, genName, CERT_EDIPartyNameTemplate, encodedName); break; case certX400Address: rv = SEC_ASN1DecodeItem(arena, genName, CERT_X400AddressTemplate, encodedName); break; case certDirectoryName: rv = SEC_ASN1DecodeItem (arena, genName, CERT_DirectoryNameTemplate, encodedName); if (rv != SECSuccess) { goto loser; } rv = SEC_ASN1DecodeItem (arena, &(genName->name.directoryName), CERT_NameTemplate, &(genName->derDirectoryName)); break; } if (rv != SECSuccess) { goto loser; } genName->type = genNameType; genName->l.next = (PRCList *) ((char *) genName) + offsetof(CERTGeneralName, l); genName->l.prev = genName->l.next; return genName;loser: return NULL;}CERTGeneralName *cert_DecodeGeneralNames (PRArenaPool *arena, SECItem **encodedGenName){ PRCList *head = NULL; PRCList *tail = NULL; CERTGeneralName *currentName = NULL; PORT_Assert(arena); if (!encodedGenName) { goto loser; } while (*encodedGenName != NULL) { currentName = cert_DecodeGeneralName(arena, *encodedGenName, NULL); if (currentName == NULL) { goto loser; } if (head == NULL) { head = &(currentName->l); tail = head; } currentName->l.next = head; currentName->l.prev = tail; tail = &(currentName->l); (cert_get_prev_general_name(currentName))->l.next = tail; encodedGenName++; } (cert_get_next_general_name(currentName))->l.prev = tail; return cert_get_next_general_name(currentName);loser: return NULL;}voidCERT_DestroyGeneralName(CERTGeneralName *name){ cert_DestroyGeneralNames(name);}SECStatuscert_DestroyGeneralNames(CERTGeneralName *name){ CERTGeneralName *first; CERTGeneralName *next = NULL; first = name; do { next = cert_get_next_general_name(name); PORT_Free(name); name = next; } while (name != first); return SECSuccess;}SECItem *cert_EncodeNameConstraint(CERTNameConstraint *constraint, SECItem *dest, PRArenaPool *arena){ PORT_Assert(arena); if (dest == NULL) { dest = (SECItem *) PORT_ArenaZAlloc(arena, sizeof(SECItem)); if (dest == NULL) { return NULL; } } cert_EncodeGeneralName(&(constraint->name), &(constraint->DERName), arena); dest = SEC_ASN1EncodeItem (arena, dest, constraint, CERTNameConstraintTemplate); return dest;} SECStatus cert_EncodeNameConstraintSubTree(CERTNameConstraint *constraints, PRArenaPool *arena, SECItem ***dest, PRBool permited){ CERTNameConstraint *current_constraint = constraints; SECItem **items = NULL; int count = 0; int i; PRCList *head; PORT_Assert(arena); if (constraints != NULL) { count = 1; } head = (PRCList *) (((char *) constraints) + offsetof(CERTNameConstraint, l)); while (current_constraint->l.next != head) { current_constraint = cert_get_next_name_constraint(current_constraint); ++count; } current_constraint = cert_get_next_name_constraint(current_constraint); items = (SECItem **) PORT_ArenaZAlloc(arena, sizeof(SECItem *) * (count + 1)); if (items == NULL) { goto loser; } for (i = 0; i < count; i++) { items[i] = cert_EncodeNameConstraint(current_constraint, (SECItem *) NULL, arena); if (items[i] == NULL) { goto loser; } current_constraint = cert_get_next_name_constraint(current_constraint); } *dest = items; if (*dest == NULL) { goto loser; } return SECSuccess;loser: return SECFailure;}SECStatus cert_EncodeNameConstraints(CERTNameConstraints *constraints, PRArenaPool *arena, SECItem *dest){ SECStatus rv = SECSuccess;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?