certreq.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:6k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. #include "cert.h"
  34. #include "secder.h"
  35. #include "key.h"
  36. #include "secitem.h"
  37. #include "secasn1.h"
  38. const SEC_ASN1Template CERT_AttributeTemplate[] = {
  39.     { SEC_ASN1_SEQUENCE,
  40. 0, NULL, sizeof(CERTAttribute) },
  41.     { SEC_ASN1_OBJECT_ID, offsetof(CERTAttribute, attrType) },
  42.     { SEC_ASN1_SET_OF, offsetof(CERTAttribute, attrValue),
  43. SEC_AnyTemplate },
  44.     { 0 }
  45. };
  46. const SEC_ASN1Template CERT_SetOfAttributeTemplate[] = {
  47.     { SEC_ASN1_SET_OF, 0, CERT_AttributeTemplate },
  48. };
  49. const SEC_ASN1Template CERT_CertificateRequestTemplate[] = {
  50.     { SEC_ASN1_SEQUENCE,
  51.   0, NULL, sizeof(CERTCertificateRequest) },
  52.     { SEC_ASN1_INTEGER,
  53.   offsetof(CERTCertificateRequest,version) },
  54.     { SEC_ASN1_INLINE,
  55.   offsetof(CERTCertificateRequest,subject),
  56.   CERT_NameTemplate },
  57.     { SEC_ASN1_INLINE,
  58.   offsetof(CERTCertificateRequest,subjectPublicKeyInfo),
  59.   CERT_SubjectPublicKeyInfoTemplate },
  60.     { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
  61.   offsetof(CERTCertificateRequest,attributes), 
  62.   CERT_SetOfAttributeTemplate },
  63.     { 0 }
  64. };
  65. CERTCertificate *
  66. CERT_CreateCertificate(unsigned long serialNumber,
  67.       CERTName *issuer,
  68.       CERTValidity *validity,
  69.       CERTCertificateRequest *req)
  70. {
  71.     CERTCertificate *c;
  72.     int rv;
  73.     PRArenaPool *arena;
  74.     
  75.     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  76.     
  77.     if ( !arena ) {
  78. return(0);
  79.     }
  80.     c = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));
  81.     
  82.     if (c) {
  83. c->referenceCount = 1;
  84. c->arena = arena;
  85. /*
  86.  * Default is a plain version 1.
  87.  * If extensions are added, it will get changed as appropriate.
  88.  */
  89. rv = DER_SetUInteger(arena, &c->version, SEC_CERTIFICATE_VERSION_1);
  90. if (rv) goto loser;
  91. rv = DER_SetUInteger(arena, &c->serialNumber, serialNumber);
  92. if (rv) goto loser;
  93. rv = CERT_CopyName(arena, &c->issuer, issuer);
  94. if (rv) goto loser;
  95. rv = CERT_CopyValidity(arena, &c->validity, validity);
  96. if (rv) goto loser;
  97. rv = CERT_CopyName(arena, &c->subject, &req->subject);
  98. if (rv) goto loser;
  99. rv = SECKEY_CopySubjectPublicKeyInfo(arena, &c->subjectPublicKeyInfo,
  100.   &req->subjectPublicKeyInfo);
  101. if (rv) goto loser;
  102.     }
  103.     return c;
  104.   loser:
  105.     CERT_DestroyCertificate(c);
  106.     return 0;
  107. }
  108. /************************************************************************/
  109. CERTCertificateRequest *
  110. CERT_CreateCertificateRequest(CERTName *subject,
  111.      CERTSubjectPublicKeyInfo *spki,
  112.      SECItem **attributes)
  113. {
  114.     CERTCertificateRequest *certreq;
  115.     PRArenaPool *arena;
  116.     SECStatus rv;
  117.     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  118.     if ( arena == NULL ) {
  119. return NULL;
  120.     }
  121.     
  122.     certreq = (CERTCertificateRequest *)
  123. PORT_ArenaZAlloc(arena, sizeof(CERTCertificateRequest));
  124.     if (certreq != NULL) {
  125. certreq->arena = arena;
  126. rv = DER_SetUInteger(arena, &certreq->version,
  127.      SEC_CERTIFICATE_REQUEST_VERSION);
  128. if (rv != SECSuccess)
  129.     goto loser;
  130. rv = CERT_CopyName(arena, &certreq->subject, subject);
  131. if (rv != SECSuccess)
  132.     goto loser;
  133. rv = SECKEY_CopySubjectPublicKeyInfo(arena,
  134.   &certreq->subjectPublicKeyInfo,
  135.   spki);
  136. if (rv != SECSuccess)
  137.     goto loser;
  138. /* Copy over attribute information */
  139. if (attributes) {
  140.     int i = 0;
  141.     /* allocate space for attributes */
  142.     while(attributes[i] != NULL) i++;
  143.     certreq->attributes = (SECItem**)PORT_ArenaZAlloc(arena, 
  144.           sizeof(SECItem *) * (i + 1));
  145.     if(!certreq->attributes) {
  146. goto loser;
  147.     }
  148.     /* copy attributes */
  149.     i = 0;
  150.     while(attributes[i]) {
  151. /*
  152. ** Attributes are a SetOf Attribute which implies
  153. ** lexigraphical ordering.  It is assumes that the
  154. ** attributes are passed in sorted.  If we need to
  155. ** add functionality to sort them, there is an
  156. ** example in the PKCS 7 code.
  157. */
  158. certreq->attributes[i] = (SECItem*)PORT_ArenaZAlloc(arena, 
  159.        sizeof(SECItem));
  160. if(!certreq->attributes[i]) {
  161.     goto loser;
  162. };
  163. rv = SECITEM_CopyItem(arena, certreq->attributes[i], 
  164.       attributes[i]);
  165. if (rv != SECSuccess) {
  166.     goto loser;
  167. }
  168. i++;
  169.     }
  170.     certreq->attributes[i] = NULL;
  171. } else {
  172.     /*
  173.      ** Invent empty attribute information. According to the
  174.      ** pkcs#10 spec, attributes has this ASN.1 type:
  175.      **
  176.      ** attributes [0] IMPLICIT Attributes
  177.      ** 
  178.      ** Which means, we should create a NULL terminated list
  179.      ** with the first entry being NULL;
  180.      */
  181.     certreq->attributes = (SECItem**)PORT_ArenaZAlloc(arena, sizeof(SECItem *));
  182.     if(!certreq->attributes) {
  183. goto loser;
  184.     }
  185.     certreq->attributes[0] = NULL;
  186.     } else {
  187. PORT_FreeArena(arena, PR_FALSE);
  188.     }
  189.     return certreq;
  190. loser:
  191.     CERT_DestroyCertificateRequest(certreq);
  192.     return NULL;
  193. }
  194. void
  195. CERT_DestroyCertificateRequest(CERTCertificateRequest *req)
  196. {
  197.     if (req && req->arena) {
  198. PORT_FreeArena(req->arena, PR_FALSE);
  199.     }
  200.     return;
  201. }