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

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 "secoid.h"
  35. #include "secder.h" /* XXX remove this when remove the DERTemplates */
  36. #include "secasn1.h"
  37. #include "secitem.h"
  38. #include <stdarg.h>
  39. #include "secerr.h"
  40. static const SEC_ASN1Template cert_AVATemplate[] = {
  41.     { SEC_ASN1_SEQUENCE,
  42.   0, NULL, sizeof(CERTAVA) },
  43.     { SEC_ASN1_OBJECT_ID,
  44.   offsetof(CERTAVA,type), },
  45.     { SEC_ASN1_ANY,
  46.   offsetof(CERTAVA,value), },
  47.     { 0, }
  48. };
  49. const SEC_ASN1Template CERT_RDNTemplate[] = {
  50.     { SEC_ASN1_SET_OF,
  51.   offsetof(CERTRDN,avas), cert_AVATemplate, sizeof(CERTRDN) }
  52. };
  53. static int
  54. CountArray(void **array)
  55. {
  56.     int count = 0;
  57.     if (array) {
  58. while (*array++) {
  59.     count++;
  60. }
  61.     }
  62.     return count;
  63. }
  64. static void
  65. **AddToArray(PRArenaPool *arena, void **array, void *element)
  66. {
  67.     unsigned count;
  68.     void **ap;
  69.     /* Count up number of slots already in use in the array */
  70.     count = 0;
  71.     ap = array;
  72.     if (ap) {
  73. while (*ap++) {
  74.     count++;
  75. }
  76.     }
  77.     if (array) {
  78. array = (void**) PORT_ArenaGrow(arena, array,
  79. (count + 1) * sizeof(void *),
  80. (count + 2) * sizeof(void *));
  81.     } else {
  82. array = (void**) PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *));
  83.     }
  84.     if (array) {
  85. array[count] = element;
  86. array[count+1] = 0;
  87.     }
  88.     return array;
  89. }
  90. #if 0
  91. static void
  92. **RemoveFromArray(void **array, void *element)
  93. {
  94.     unsigned count;
  95.     void **ap;
  96.     int slot;
  97.     /* Look for element */
  98.     ap = array;
  99.     if (ap) {
  100. count = 1; /* count the null at the end */
  101. slot = -1;
  102. for (; *ap; ap++, count++) {
  103.     if (*ap == element) {
  104. /* Found it */
  105. slot = ap - array;
  106.     }
  107. }
  108. if (slot >= 0) {
  109.     /* Found it. Squish array down */
  110.     PORT_Memmove((void*) (array + slot), (void*) (array + slot + 1),
  111.        (count - slot - 1) * sizeof(void*));
  112.     /* Don't bother reallocing the memory */
  113. }
  114.     }
  115.     return array;
  116. }
  117. #endif /* 0 */
  118. SECOidTag
  119. CERT_GetAVATag(CERTAVA *ava)
  120. {
  121.     SECOidData *oid;
  122.     if (!ava->type.data) return (SECOidTag)-1;
  123.     oid = SECOID_FindOID(&ava->type);
  124.     
  125.     if ( oid ) {
  126. return(oid->offset);
  127.     }
  128.     return (SECOidTag)-1;
  129. }
  130. static SECStatus
  131. SetupAVAType(PRArenaPool *arena, SECOidTag type, SECItem *it, unsigned *maxLenp)
  132. {
  133.     unsigned char *oid;
  134.     unsigned oidLen;
  135.     unsigned char *cp;
  136.     unsigned maxLen;
  137.     SECOidData *oidrec;
  138.     oidrec = SECOID_FindOIDByTag(type);
  139.     if (oidrec == NULL)
  140. return SECFailure;
  141.     oid = oidrec->oid.data;
  142.     oidLen = oidrec->oid.len;
  143.     switch (type) {
  144.       case SEC_OID_AVA_COUNTRY_NAME:
  145. maxLen = 2;
  146. break;
  147.       case SEC_OID_AVA_ORGANIZATION_NAME:
  148. maxLen = 64;
  149. break;
  150.       case SEC_OID_AVA_COMMON_NAME:
  151. maxLen = 64;
  152. break;
  153.       case SEC_OID_AVA_LOCALITY:
  154. maxLen = 128;
  155. break;
  156.       case SEC_OID_AVA_STATE_OR_PROVINCE:
  157. maxLen = 128;
  158. break;
  159.       case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:
  160. maxLen = 64;
  161. break;
  162.       case SEC_OID_AVA_DC:
  163. maxLen = 128;
  164. break;
  165.       case SEC_OID_AVA_DN_QUALIFIER:
  166. maxLen = 0x7fff;
  167. break;
  168.       case SEC_OID_PKCS9_EMAIL_ADDRESS:
  169. maxLen = 128;
  170. break;
  171.       case SEC_OID_RFC1274_UID:
  172. maxLen = 256;  /* RFC 1274 specifies 256 */
  173. break;
  174.       case SEC_OID_RFC1274_MAIL:
  175. maxLen = 256;  /* RFC 1274 specifies 256 */
  176. break; 
  177.       default:
  178. PORT_SetError(SEC_ERROR_INVALID_ARGS);
  179. return SECFailure;
  180.     }
  181.     it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, oidLen);
  182.     if (cp == NULL) {
  183. return SECFailure;
  184.     }
  185.     it->len = oidLen;
  186.     PORT_Memcpy(cp, oid, oidLen);
  187.     *maxLenp = maxLen;
  188.     return SECSuccess;
  189. }
  190. static SECStatus
  191. SetupAVAValue(PRArenaPool *arena, int valueType, char *value, SECItem *it,
  192.       unsigned maxLen)
  193. {
  194.     unsigned valueLen, valueLenLen, total;
  195.     unsigned ucs4Len = 0, ucs4MaxLen;
  196.     unsigned char *cp, *ucs4Val;
  197.     switch (valueType) {
  198.       case SEC_ASN1_PRINTABLE_STRING:
  199.       case SEC_ASN1_IA5_STRING:
  200.       case SEC_ASN1_T61_STRING:
  201. valueLen = PORT_Strlen(value);
  202. break;
  203.       case SEC_ASN1_UNIVERSAL_STRING:
  204. valueLen = PORT_Strlen(value);
  205. ucs4Val = (unsigned char *)PORT_ArenaZAlloc(arena, 
  206.     PORT_Strlen(value) * 6);
  207. ucs4MaxLen = PORT_Strlen(value) * 6;
  208. if(!ucs4Val || !PORT_UCS4_UTF8Conversion(PR_TRUE, (unsigned char *)value, valueLen,
  209. ucs4Val, ucs4MaxLen, &ucs4Len)) {
  210.     PORT_SetError(SEC_ERROR_INVALID_ARGS);
  211.     return SECFailure;
  212. }
  213. value = (char *)ucs4Val;
  214. valueLen = ucs4Len;
  215. break;
  216.       default:
  217. PORT_SetError(SEC_ERROR_INVALID_ARGS);
  218. return SECFailure;
  219.     }
  220.     if (((valueType != SEC_ASN1_UNIVERSAL_STRING) && (valueLen > maxLen)) ||
  221. (valueType == SEC_ASN1_UNIVERSAL_STRING) && (valueLen > (maxLen * 4))) {
  222. PORT_SetError(SEC_ERROR_INVALID_ARGS);
  223. return SECFailure;
  224.     } 
  225.     valueLenLen = DER_LengthLength(valueLen);
  226.     total = 1 + valueLenLen + valueLen;
  227.     it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, total);
  228.     if (!cp) {
  229. return SECFailure;
  230.     }
  231.     it->len = total;
  232.     cp = (unsigned char*) DER_StoreHeader(cp, valueType, valueLen);
  233.     PORT_Memcpy(cp, value, valueLen);
  234.     return SECSuccess;
  235. }
  236. CERTAVA *
  237. CERT_CreateAVA(PRArenaPool *arena, SECOidTag kind, int valueType, char *value)
  238. {
  239.     CERTAVA *ava;
  240.     int rv;
  241.     unsigned maxLen;
  242.     ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
  243.     if (ava) {
  244. rv = SetupAVAType(arena, kind, &ava->type, &maxLen);
  245. if (rv) {
  246.     /* Illegal AVA type */
  247.     return 0;
  248. }
  249. rv = SetupAVAValue(arena, valueType, value, &ava->value, maxLen);
  250. if (rv) {
  251.     /* Illegal value type */
  252.     return 0;
  253. }
  254.     }
  255.     return ava;
  256. }
  257. CERTAVA *
  258. CERT_CopyAVA(PRArenaPool *arena, CERTAVA *from)
  259. {
  260.     CERTAVA *ava;
  261.     int rv;
  262.     ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
  263.     if (ava) {
  264. rv = SECITEM_CopyItem(arena, &ava->type, &from->type);
  265. if (rv) goto loser;
  266. rv = SECITEM_CopyItem(arena, &ava->value, &from->value);
  267. if (rv) goto loser;
  268.     }
  269.     return ava;
  270.   loser:
  271.     return 0;
  272. }
  273. /************************************************************************/
  274. /* XXX This template needs to go away in favor of the new SEC_ASN1 version. */
  275. static const SEC_ASN1Template cert_RDNTemplate[] = {
  276.     { SEC_ASN1_SET_OF,
  277.   offsetof(CERTRDN,avas), cert_AVATemplate, sizeof(CERTRDN) }
  278. };
  279. CERTRDN *
  280. CERT_CreateRDN(PRArenaPool *arena, CERTAVA *ava0, ...)
  281. {
  282.     CERTAVA *ava;
  283.     CERTRDN *rdn;
  284.     va_list ap;
  285.     unsigned count;
  286.     CERTAVA **avap;
  287.     rdn = (CERTRDN*) PORT_ArenaAlloc(arena, sizeof(CERTRDN));
  288.     if (rdn) {
  289. /* Count number of avas going into the rdn */
  290. count = 1;
  291. va_start(ap, ava0);
  292. while ((ava = va_arg(ap, CERTAVA*)) != 0) {
  293.     count++;
  294. }
  295. va_end(ap);
  296. /* Now fill in the pointers */
  297. rdn->avas = avap =
  298.     (CERTAVA**) PORT_ArenaAlloc( arena, (count + 1)*sizeof(CERTAVA*));
  299. if (!avap) {
  300.     return 0;
  301. }
  302. *avap++ = ava0;
  303. va_start(ap, ava0);
  304. while ((ava = va_arg(ap, CERTAVA*)) != 0) {
  305.     *avap++ = ava;
  306. }
  307. va_end(ap);
  308. *avap++ = 0;
  309.     }
  310.     return rdn;
  311. }
  312. SECStatus
  313. CERT_AddAVA(PRArenaPool *arena, CERTRDN *rdn, CERTAVA *ava)
  314. {
  315.     rdn->avas = (CERTAVA**) AddToArray(arena, (void**) rdn->avas, ava);
  316.     return rdn->avas ? SECSuccess : SECFailure;
  317. }
  318. SECStatus
  319. CERT_CopyRDN(PRArenaPool *arena, CERTRDN *to, CERTRDN *from)
  320. {
  321.     CERTAVA **avas, *fava, *tava;
  322.     SECStatus rv;
  323.     /* Copy each ava from from */
  324.     avas = from->avas;
  325.     while ((fava = *avas++) != 0) {
  326. tava = CERT_CopyAVA(arena, fava);
  327. if (!tava) return SECFailure;
  328. rv = CERT_AddAVA(arena, to, tava);
  329. if (rv) return rv;
  330.     }
  331.     return SECSuccess;
  332. }
  333. /************************************************************************/
  334. const SEC_ASN1Template CERT_NameTemplate[] = {
  335.     { SEC_ASN1_SEQUENCE_OF,
  336.   offsetof(CERTName,rdns), CERT_RDNTemplate, sizeof(CERTName) }
  337. };
  338. CERTName *
  339. CERT_CreateName(CERTRDN *rdn0, ...)
  340. {
  341.     CERTRDN *rdn;
  342.     CERTName *name;
  343.     va_list ap;
  344.     unsigned count;
  345.     CERTRDN **rdnp;
  346.     PRArenaPool *arena;
  347.     
  348.     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  349.     if ( !arena ) {
  350. return(0);
  351.     }
  352.     
  353.     name = (CERTName*) PORT_ArenaAlloc(arena, sizeof(CERTName));
  354.     if (name) {
  355. name->arena = arena;
  356. /* Count number of RDNs going into the Name */
  357. if (!rdn0) {
  358.     count = 0;
  359. } else {
  360.     count = 1;
  361.     va_start(ap, rdn0);
  362.     while ((rdn = va_arg(ap, CERTRDN*)) != 0) {
  363. count++;
  364.     }
  365.     va_end(ap);
  366. }
  367. /* Allocate space (including space for terminal null ptr) */
  368. name->rdns = rdnp =
  369.     (CERTRDN**) PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTRDN*));
  370. if (!name->rdns) {
  371.     goto loser;
  372. }
  373. /* Now fill in the pointers */
  374. if (count > 0) {
  375.     *rdnp++ = rdn0;
  376.     va_start(ap, rdn0);
  377.     while ((rdn = va_arg(ap, CERTRDN*)) != 0) {
  378. *rdnp++ = rdn;
  379.     }
  380.     va_end(ap);
  381. }
  382. /* null terminate the list */
  383. *rdnp++ = 0;
  384.     }
  385.     return name;
  386. loser:
  387.     PORT_FreeArena(arena, PR_FALSE);
  388.     return(0);
  389. }
  390. void
  391. CERT_DestroyName(CERTName *name)
  392. {
  393.     if (name)
  394.     {
  395.         PRArenaPool *arena = name->arena;
  396.         name->rdns = NULL;
  397. name->arena = NULL;
  398. if (arena) PORT_FreeArena(arena, PR_FALSE);
  399.     }
  400. }
  401. SECStatus
  402. CERT_AddRDN(CERTName *name, CERTRDN *rdn)
  403. {
  404.     name->rdns = (CERTRDN**) AddToArray(name->arena, (void**) name->rdns, rdn);
  405.     return name->rdns ? SECSuccess : SECFailure;
  406. }
  407. SECStatus
  408. CERT_CopyName(PRArenaPool *arena, CERTName *to, CERTName *from)
  409. {
  410.     CERTRDN **rdns, *frdn, *trdn;
  411.     SECStatus rv;
  412.     CERT_DestroyName(to);
  413.     to->arena = arena;
  414.     /* Copy each rdn from from */
  415.     rdns = from->rdns;
  416.     while ((frdn = *rdns++) != 0) {
  417. trdn = CERT_CreateRDN(arena, 0);
  418. if ( trdn == NULL ) {
  419.     return(SECFailure);
  420. }
  421. rv = CERT_CopyRDN(arena, trdn, frdn);
  422. if (rv) return rv;
  423. rv = CERT_AddRDN(to, trdn);
  424. if (rv) return rv;
  425.     }
  426.     return SECSuccess;
  427. }
  428. /************************************************************************/
  429. SECComparison
  430. CERT_CompareAVA(CERTAVA *a, CERTAVA *b)
  431. {
  432.     SECComparison rv;
  433.     rv = SECITEM_CompareItem(&a->type, &b->type);
  434.     if (rv) {
  435. /*
  436. ** XXX for now we are going to just assume that a bitwise
  437. ** comparison of the value codes will do the trick.
  438. */
  439.     }
  440.     rv = SECITEM_CompareItem(&a->value, &b->value);
  441.     return rv;
  442. }
  443. SECComparison
  444. CERT_CompareRDN(CERTRDN *a, CERTRDN *b)
  445. {
  446.     CERTAVA **aavas, *aava;
  447.     CERTAVA **bavas, *bava;
  448.     int ac, bc;
  449.     SECComparison rv = SECEqual;
  450.     aavas = a->avas;
  451.     bavas = b->avas;
  452.     /*
  453.     ** Make sure array of ava's are the same length. If not, then we are
  454.     ** not equal
  455.     */
  456.     ac = CountArray((void**) aavas);
  457.     bc = CountArray((void**) bavas);
  458.     if (ac < bc) return SECLessThan;
  459.     if (ac > bc) return SECGreaterThan;
  460.     for (;;) {
  461. aava = *aavas++;
  462. bava = *bavas++;
  463. if (!aava) {
  464.     break;
  465. }
  466. rv = CERT_CompareAVA(aava, bava);
  467. if (rv) return rv;
  468.     }
  469.     return rv;
  470. }
  471. SECComparison
  472. CERT_CompareName(CERTName *a, CERTName *b)
  473. {
  474.     CERTRDN **ardns, *ardn;
  475.     CERTRDN **brdns, *brdn;
  476.     int ac, bc;
  477.     SECComparison rv = SECEqual;
  478.     ardns = a->rdns;
  479.     brdns = b->rdns;
  480.     /*
  481.     ** Make sure array of rdn's are the same length. If not, then we are
  482.     ** not equal
  483.     */
  484.     ac = CountArray((void**) ardns);
  485.     bc = CountArray((void**) brdns);
  486.     if (ac < bc) return SECLessThan;
  487.     if (ac > bc) return SECGreaterThan;
  488.     for (;;) {
  489. ardn = *ardns++;
  490. brdn = *brdns++;
  491. if (!ardn) {
  492.     break;
  493. }
  494. rv = CERT_CompareRDN(ardn, brdn);
  495. if (rv) return rv;
  496.     }
  497.     return rv;
  498. }
  499. /* Moved from certhtml.c */
  500. SECItem *
  501. CERT_DecodeAVAValue(SECItem *derAVAValue)
  502. {
  503.           SECItem          *retItem; 
  504.     const SEC_ASN1Template *theTemplate       = NULL;
  505.           PRBool            convertUCS4toUTF8 = PR_FALSE;
  506.           PRBool            convertUCS2toUTF8 = PR_FALSE;
  507.           SECItem           avaValue          = {siBuffer, 0}; 
  508.     if(!derAVAValue) {
  509. return NULL;
  510.     }
  511.     switch(derAVAValue->data[0]) {
  512. case SEC_ASN1_UNIVERSAL_STRING:
  513.     convertUCS4toUTF8 = PR_TRUE;
  514.     theTemplate = SEC_UniversalStringTemplate;
  515.     break;
  516. case SEC_ASN1_IA5_STRING:
  517.     theTemplate = SEC_IA5StringTemplate;
  518.     break;
  519. case SEC_ASN1_PRINTABLE_STRING:
  520.     theTemplate = SEC_PrintableStringTemplate;
  521.     break;
  522. case SEC_ASN1_T61_STRING:
  523.     theTemplate = SEC_T61StringTemplate;
  524.     break;
  525. case SEC_ASN1_BMP_STRING:
  526.     convertUCS2toUTF8 = PR_TRUE;
  527.     theTemplate = SEC_BMPStringTemplate;
  528.     break;
  529. case SEC_ASN1_UTF8_STRING:
  530.     /* No conversion needed ! */
  531.     theTemplate = SEC_UTF8StringTemplate;
  532.     break;
  533. default:
  534.     return NULL;
  535.     }
  536.     PORT_Memset(&avaValue, 0, sizeof(SECItem));
  537.     if(SEC_ASN1DecodeItem(NULL, &avaValue, theTemplate, derAVAValue) 
  538. != SECSuccess) {
  539. return NULL;
  540.     }
  541.     if (convertUCS4toUTF8) {
  542. unsigned int   utf8ValLen = avaValue.len * 3;
  543. unsigned char *utf8Val    = (unsigned char*)PORT_ZAlloc(utf8ValLen);
  544. if(!PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len,
  545.      utf8Val, utf8ValLen, &utf8ValLen)) {
  546.     PORT_Free(utf8Val);
  547.     PORT_Free(avaValue.data);
  548.     return NULL;
  549. }
  550. PORT_Free(avaValue.data);
  551. avaValue.data = utf8Val;
  552. avaValue.len = utf8ValLen;
  553.     } else if (convertUCS2toUTF8) {
  554. unsigned int   utf8ValLen = avaValue.len * 3;
  555. unsigned char *utf8Val    = (unsigned char*)PORT_ZAlloc(utf8ValLen);
  556. if(!PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len,
  557.      utf8Val, utf8ValLen, &utf8ValLen)) {
  558.     PORT_Free(utf8Val);
  559.     PORT_Free(avaValue.data);
  560.     return NULL;
  561. }
  562. PORT_Free(avaValue.data);
  563. avaValue.data = utf8Val;
  564. avaValue.len = utf8ValLen;
  565.     }
  566.     retItem = SECITEM_DupItem(&avaValue);
  567.     PORT_Free(avaValue.data);
  568.     return retItem;
  569. }