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 + -
显示快捷键?