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

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 <stdio.h>
  34. #include <fcntl.h>
  35. #include <sys/types.h>
  36. #ifdef XP_UNIX
  37. #include <unistd.h>
  38. #endif
  39. #include "cryptint.h"
  40. #include "blapi.h" /* program calls low level functions directly!*/
  41. #include "pk11func.h"
  42. #include "secmod.h"
  43. #include "secmodi.h"
  44. #include "cert.h"
  45. #include "cdbhdl.h"
  46. #include "key.h"
  47. #include "swforti.h"
  48. #include "secutil.h"
  49. #include "secrng.h"
  50. #ifndef O_BINARY
  51. #define O_BINARY 0
  52. #endif
  53. #define MAX_PERSONALITIES 50
  54. typedef struct {
  55.     int index;
  56.     CI_CERT_STR label;
  57.     CERTCertificate *cert;
  58. } certlist;
  59. typedef struct {
  60.    int card;
  61.    int index;
  62.    CI_CERT_STR label;
  63.    certlist valid[MAX_PERSONALITIES];
  64.    int count;
  65. } Cert;
  66. #define EMAIL_OID_LEN 9
  67. #define EMAIL_OID 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01
  68. unsigned char emailAVA[127] = {
  69. 0x31, 6+EMAIL_OID_LEN,  /* Set */
  70. 0x30, 4+EMAIL_OID_LEN, /* Sequence */
  71. 0x06, EMAIL_OID_LEN, EMAIL_OID,
  72. 0x13, 0, /* printable String */
  73. };
  74. #define EMAIL_DATA_START 8+EMAIL_OID_LEN
  75. int emailOffset[] = { 1, 3, EMAIL_DATA_START-1 };
  76. int offsetCount = sizeof(emailOffset)/sizeof(emailOffset[0]);
  77. unsigned char hash[20] = { 'H', 'a', 's', 'h', ' ', 'F', 'a', 'i', 'l', 'e',
  78.   'd', ' ', '*', '*', '*', '*', '*', '*', '*', '*' };
  79. unsigned char sig[40] = { 'H', 'a', 's', 'h', ' ', 'F', 'a', 'i', 'l', 'e',
  80.  'd', ' ', '*', '*', '*', '*', '*', '*', '*', '*',
  81.  '>', '>', '>', ' ', 'N', 'o', 't', ' ', 'S', 'i',
  82.  'g', 'n', 'd', ' ', '<', '<', '<', ' ', ' ', ' ' };
  83. /*void *malloc(int); */
  84. unsigned char *data_start(unsigned char *buf, int length, int *data_length) 
  85. {
  86.     unsigned char tag;
  87.     int used_length= 0;
  88.     tag = buf[used_length++];
  89.     /* blow out when we come to the end */
  90.     if (tag == 0) {
  91. return NULL;
  92.     }
  93.     *data_length = buf[used_length++];
  94.     if (*data_length&0x80) {
  95. int  len_count = *data_length & 0x7f;
  96. *data_length = 0;
  97. while (len_count-- > 0) {
  98.     *data_length = (*data_length << 8) | buf[used_length++];
  99.     }
  100.     if (*data_length > (length-used_length) ) {
  101. *data_length = length-used_length;
  102. return NULL;
  103.     }
  104.     return (buf + used_length);
  105. }
  106. unsigned char *
  107. GetAbove(unsigned char *cert,int cert_length,int *above_len)
  108. {
  109. unsigned char *buf = cert;
  110. int buf_length = cert_length;
  111. unsigned char *tmp;
  112. int len;
  113. *above_len = 0;
  114. /* optional serial number */
  115. if ((buf[0] & 0xa0) == 0xa0) {
  116.     tmp = data_start(buf,buf_length,&len);
  117.     if (tmp == NULL) return NULL;
  118.     buf_length -= (tmp-buf) + len;
  119.     buf = tmp + len;
  120. }
  121.         /* serial number */
  122. tmp = data_start(buf,buf_length,&len);
  123. if (tmp == NULL) return NULL;
  124. buf_length -= (tmp-buf) + len;
  125. buf = tmp + len;
  126. /* skip the OID */
  127. tmp = data_start(buf,buf_length,&len);
  128. if (tmp == NULL) return NULL;
  129. buf_length -= (tmp-buf) + len;
  130. buf = tmp + len;
  131. /* issuer */
  132. tmp = data_start(buf,buf_length,&len);
  133. if (tmp == NULL) return NULL;
  134. buf_length -= (tmp-buf) + len;
  135. buf = tmp + len;
  136. /* skip the date */
  137. tmp = data_start(buf,buf_length,&len);
  138. if (tmp == NULL) return NULL;
  139. buf_length -= (tmp-buf) + len;
  140. buf = tmp + len;
  141. *above_len = buf - cert;
  142. return cert;
  143. }
  144. unsigned char *
  145. GetSubject(unsigned char *cert,int cert_length,int *subj_len) {
  146. unsigned char *buf = cert;
  147. int buf_length = cert_length;
  148. unsigned char *tmp;
  149. int len;
  150. *subj_len = 0;
  151. /* optional serial number */
  152. if ((buf[0] & 0xa0) == 0xa0) {
  153.     tmp = data_start(buf,buf_length,&len);
  154.     if (tmp == NULL) return NULL;
  155.     buf_length -= (tmp-buf) + len;
  156.     buf = tmp + len;
  157. }
  158.         /* serial number */
  159. tmp = data_start(buf,buf_length,&len);
  160. if (tmp == NULL) return NULL;
  161. buf_length -= (tmp-buf) + len;
  162. buf = tmp + len;
  163. /* skip the OID */
  164. tmp = data_start(buf,buf_length,&len);
  165. if (tmp == NULL) return NULL;
  166. buf_length -= (tmp-buf) + len;
  167. buf = tmp + len;
  168. /* issuer */
  169. tmp = data_start(buf,buf_length,&len);
  170. if (tmp == NULL) return NULL;
  171. buf_length -= (tmp-buf) + len;
  172. buf = tmp + len;
  173. /* skip the date */
  174. tmp = data_start(buf,buf_length,&len);
  175. if (tmp == NULL) return NULL;
  176. buf_length -= (tmp-buf) + len;
  177. buf = tmp + len;
  178. return data_start(buf,buf_length,subj_len);
  179. }
  180. unsigned char *
  181. GetBelow(unsigned char *cert,int cert_length,int *below_len) {
  182. unsigned char *subj;
  183. int subj_len;
  184. unsigned char *below;
  185. *below_len = 0;
  186. subj = GetSubject(cert,cert_length,&subj_len);
  187. below = subj + subj_len;
  188. *below_len = cert_length - (below - cert);
  189. return below;
  190. }
  191. unsigned char *
  192. GetSignature(unsigned char *sig,int sig_length,int *subj_len) {
  193. unsigned char *buf = sig;
  194. int buf_length = sig_length;
  195. unsigned char *tmp;
  196. int len;
  197. *subj_len = 0;
  198.         /* signature oid */
  199. tmp = data_start(buf,buf_length,&len);
  200. if (tmp == NULL) return NULL;
  201. buf_length -= (tmp-buf) + len;
  202. buf = tmp + len;
  203. /* signature data */
  204. tmp = data_start(buf,buf_length,&len);
  205. if (tmp == NULL) return NULL;
  206. *subj_len = len -1;
  207. return tmp+1;
  208. }
  209. int DER_Sequence(unsigned char *buf, int length) {
  210.     int next = 0;
  211.     buf[next++] = 0x30;
  212.     if (length < 0x80) {
  213. buf[next++] = length;
  214.     } else {
  215. buf[next++] = 0x82;
  216. buf[next++] = (length >> 8) & 0xff;
  217. buf[next++] = length & 0xff;
  218.     }
  219.     return next;
  220. }
  221. static
  222. int Cert_length(unsigned char *buf, int length) {
  223.     unsigned char tag;
  224.     int used_length= 0;
  225.     int data_length;
  226.     tag = buf[used_length++];
  227.     /* blow out when we come to the end */
  228.     if (tag == 0) {
  229.         return 0;
  230.     }
  231.     data_length = buf[used_length++];
  232.     if (data_length&0x80) {
  233.         int  len_count = data_length & 0x7f;
  234.         data_length = 0;
  235.         while (len_count-- > 0) {
  236.             data_length = (data_length << 8) | buf[used_length++];
  237.         }
  238.     }
  239.     if (data_length > (length-used_length) ) {
  240.         return length;
  241.     }
  242.     return (data_length + used_length);
  243. }
  244. int
  245. InitCard(int card, char *inpass) {
  246.     int cirv;
  247.     char buf[50];
  248.     char *pass;
  249.     cirv = CI_Open( 0 /* flags */, card);
  250.     if (cirv != CI_OK) return cirv;
  251.     if (inpass == NULL) {
  252.         sprintf(buf,"Enter PIN for card in socket %d: ",card);
  253.         pass = SECU_GetPasswordString(NULL, buf);
  254.         if (pass == NULL) {
  255.     CI_Close(CI_POWER_DOWN_FLAG,card);
  256.     return CI_FAIL;
  257.         }
  258.     } else pass=inpass;
  259.     cirv = CI_CheckPIN(CI_USER_PIN,(unsigned char *)pass);
  260.     if (cirv != CI_OK)  {
  261. CI_Close(CI_POWER_DOWN_FLAG,card);
  262.     }
  263.     return cirv;
  264. }
  265. int
  266. isUser(CI_PERSON *person) {
  267.     return 1;
  268. }
  269. int
  270. isCA(CI_PERSON *person) {
  271.     return 0;
  272. }
  273. int FoundCert(int card, char *name, Cert *cert) {
  274.     CI_PERSON personalities[MAX_PERSONALITIES];
  275.     CI_PERSON *person;
  276.     int cirv;
  277.     int i;
  278.     int user_len = strlen(name);
  279.     PORT_Memset(personalities, 0, sizeof(CI_PERSON)*MAX_PERSONALITIES);
  280.     cirv = CI_GetPersonalityList(MAX_PERSONALITIES,personalities);
  281.     if (cirv != CI_OK) return 0;
  282.     cert->count = 1;
  283.     cert->valid[0].index = 0;
  284.     memcpy(cert->valid[0].label,"RRXX0000Root PAA Certificate        ",
  285. sizeof(cert->valid[0].label));
  286.     cert->valid[0].cert = NULL;
  287.     for (i=0; i < MAX_PERSONALITIES; i++) {
  288. person = &personalities[i];
  289. if ( (PORT_Memcmp(person->CertLabel,"RRXX",4) == 0) ||
  290.      (PORT_Memcmp(person->CertLabel,"RTXX",4) == 0) ||
  291.      (PORT_Memcmp(person->CertLabel,"LAXX",4) == 0) ||
  292.      (PORT_Memcmp(person->CertLabel,"INKS",4) == 0) ||
  293.      (PORT_Memcmp(person->CertLabel,"INKX",4) == 0) ||
  294.      (PORT_Memcmp(person->CertLabel,"ONKS",4) == 0) ||
  295.      (PORT_Memcmp(person->CertLabel,"ONKX",4) == 0) ||
  296.      (PORT_Memcmp(person->CertLabel,"KEAK",4) == 0) ||
  297.      (PORT_Memcmp(person->CertLabel,"3IKX",4) == 0) ||
  298.      (PORT_Memcmp(person->CertLabel,"DSA1",4) == 0) ||
  299.      (PORT_Memcmp(person->CertLabel,"DSAI",4) == 0) ||
  300.      (PORT_Memcmp(person->CertLabel,"DSAO",4) == 0) ||
  301.      (PORT_Memcmp(person->CertLabel,"3IXS",4) == 0) ||
  302.      (PORT_Memcmp(person->CertLabel,"3OXS",4) == 0) ){
  303.     int index;
  304.     cert->valid[cert->count].cert = NULL;
  305.     memcpy(cert->valid[cert->count].label,
  306. person->CertLabel,sizeof(person->CertLabel));
  307.     for (index = sizeof(person->CertLabel)-1;
  308. cert->valid[cert->count].label[index] == ' '; index--) {
  309. cert->valid[cert->count].label[index] = 0;
  310.     }
  311.     cert->valid[cert->count++].index = person->CertificateIndex;
  312. }
  313.     }
  314.     for (i=0; i < MAX_PERSONALITIES; i++) {
  315. person = &personalities[i];
  316. if (strncmp((char *)&person->CertLabel[8],name,user_len) == 0) {
  317.     cert->card = card;
  318.     cert->index = person->CertificateIndex;
  319.     memcpy(&cert->label,person->CertLabel,sizeof(person->CertLabel));
  320.     return 1;
  321. }
  322.     }
  323.     return 0;
  324. }
  325. void
  326. Terminate(char *mess, int cirv, int card1, int card2)
  327. {
  328.     fprintf(stderr,"FAIL: %s error %dn",mess,cirv);
  329.     if (card1 != -1) CI_Close(CI_POWER_DOWN_FLAG,card1);
  330.     if (card2 != -1) CI_Close(CI_POWER_DOWN_FLAG,card2);
  331.     CI_Terminate();
  332.     exit(1);
  333. }
  334. void
  335. usage(char *prog)
  336. {
  337.     fprintf(stderr,"usage: %s [-e email][-t transport][-u userpin][-U userpass][-s ssopin][-S ssopass][-o outfile] common_name ca_labeln",prog);
  338.     exit(1);
  339. }
  340. #define CERT_SIZE 2048
  341. /* version and oid */
  342. unsigned char header[] = {
  343.     /* Cert OID */
  344.     0x02, 0x10,
  345.      0x00, 0x00, 0x00, 0x00,
  346.      0x00, 0x00, 0x00, 0x00,
  347.      0x00, 0x00, 0x00, 0x00,
  348.      0x00, 0x00, 0x00, 0x00,
  349.     0x30, 0x0b, 0x06, 0x09,
  350.     0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01, 0x13 };
  351. #define KEY_START 21
  352. #define KMID_OFFSET 4
  353. #define KEA_OFFSET 15
  354. #define DSA_OFFSET 148
  355. unsigned char key[] = {
  356.    /* Sequence(Constructed): 293 bytes (0x125) */
  357.    0x30, 0x82, 0x01, 0x25,
  358.    /*Sequence(Constructed): 11 bytes (0xb) */
  359.    0x30, 0x0b,
  360.    /* ObjectId(Universal): 9 bytes (0x9) */
  361.    0x06, 0x09,
  362.    0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01, 0x14,
  363.    /* BitString(Universal): 276 bytes (0x114) */
  364.    0x03, 0x82, 0x01, 0x14,
  365.    0x00, 0x00, 0x01, 0xef, 0x04, 0x01, 0x00, 0x01,
  366.    0x00, 0x00, 0x69, 0x60, 0x70, 0x00, 0x80, 0x02,
  367.    0x2e, 0x46, 0xb9, 0xcb, 0x22, 0x72, 0x0b, 0x1c,
  368.    0xe6, 0x25, 0x20, 0x16, 0x86, 0x05, 0x8e, 0x2b,
  369.    0x98, 0xd1, 0x46, 0x3d, 0x00, 0xb8, 0x69, 0xe1,
  370.    0x1a, 0x42, 0x7d, 0x7d, 0xb5, 0xbf, 0x9f, 0x26,
  371.    0xd3, 0x2c, 0xb1, 0x73, 0x01, 0xb6, 0xb2, 0x6f,
  372.    0x7b, 0xa5, 0x54, 0x85, 0x60, 0x77, 0x81, 0x8a,
  373.    0x87, 0x86, 0xe0, 0x2d, 0xbf, 0xdb, 0x28, 0xe8,
  374.    0xfa, 0x20, 0x35, 0xb4, 0xc0, 0x94, 0x10, 0x8e,
  375.    0x1c, 0x58, 0xaa, 0x02, 0x60, 0x97, 0xf5, 0xb3,
  376.    0x2f, 0xf8, 0x99, 0x29, 0x28, 0x73, 0x47, 0x36,
  377.    0xdd, 0x1d, 0x78, 0x95, 0xeb, 0xb8, 0xec, 0x45,
  378.    0x96, 0x69, 0x6f, 0x54, 0xc8, 0x1f, 0x2d, 0x3a,
  379.    0xd9, 0x0e, 0x8e, 0xaa, 0x59, 0x11, 0x8c, 0x3b,
  380.    0x8d, 0xa4, 0xed, 0xf2, 0x7d, 0xdc, 0x42, 0xaa,
  381.    0xa4, 0xd2, 0x1c, 0xb9, 0x87, 0xd0, 0xd9, 0x3d,
  382.    0x8e, 0x89, 0xbb, 0x06, 0x54, 0xcf, 0x32, 0x00,
  383.    0x02, 0x00, 0x00, 0x80, 0x0b, 0x80, 0x6c, 0x0f,
  384.    0x71, 0xd1, 0xa1, 0xa9, 0x26, 0xb4, 0xf1, 0xcd,
  385.    0x6a, 0x7a, 0x09, 0xaa, 0x58, 0x28, 0xd7, 0x35,
  386.    0x74, 0x8e, 0x7c, 0x83, 0xcb, 0xfe, 0x00, 0x3b,
  387.    0x62, 0x00, 0xfb, 0x90, 0x37, 0xcd, 0x93, 0xcf,
  388.    0xf3, 0xe4, 0x6d, 0x8d, 0xdd, 0xb8, 0x53, 0xe0,
  389.    0x5c, 0xda, 0x1a, 0x7e, 0x56, 0x03, 0x95, 0x03,
  390.    0x2f, 0x74, 0x86, 0xb1, 0xa0, 0xbb, 0x05, 0x91,
  391.    0xe4, 0x76, 0x83, 0xe6, 0x62, 0xf9, 0x12, 0x64,
  392.    0x5a, 0x62, 0xd8, 0x94, 0x04, 0x1f, 0x83, 0x02,
  393.    0x2e, 0xc5, 0xa7, 0x17, 0x46, 0x46, 0x21, 0x96,
  394.    0xc3, 0xa9, 0x8e, 0x92, 0x18, 0xd1, 0x52, 0x08,
  395.    0x1d, 0xff, 0x8e, 0x24, 0xdb, 0x6c, 0xd8, 0xfe,
  396.    0x80, 0x93, 0xe1, 0xa5, 0x4a, 0x0a, 0x37, 0x24,
  397.    0x18, 0x07, 0xbe, 0x0f, 0xaf, 0x73, 0xea, 0x50,
  398.    0x64, 0xa1, 0xb3, 0x77, 0xe5, 0x41, 0x02, 0x82,
  399.    0x39, 0xb9, 0xe3, 0x94 
  400. };
  401. unsigned char valitity[] = {
  402.    0x30, 0x1e,
  403.    0x17, 0x0d,
  404.    '2','0','0','0','0','1','0','1','0','0','0','0','Z',
  405.    0x17, 0x0d,
  406.    '2','0','0','5','1','2','0','1','0','0','0','0','Z'
  407. };
  408. unsigned char cnam_oid[] = { 0x06, 0x03, 0x55, 0x04, 0x03 };
  409. unsigned char signature[] = {
  410.     /* the OID */
  411.     0x30, 0x0b, 0x06, 0x09,
  412.     0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01, 0x13,
  413.     /* signature wrap */
  414.     0x03, 0x29, 0x00,
  415.     /* 40 byte dsa signature */
  416.     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  417.     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  418.     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  419.     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  420. };
  421. unsigned char fortezza_oid [] = {
  422.     0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01, 0x13
  423. };
  424. unsigned char software_ou[] = {
  425.     0x31, 26, 0x30, 24,
  426.     0x06, 0x03, 0x55, 0x04, 0x0b,
  427.     0x13, 17, 
  428.       'S','o','f','t','w',
  429.       'a','r','e',' ','F',
  430.       'O','R','T','E','Z','Z','A'
  431. };
  432. char letterarray[] = {
  433. 'a','b','c','d','e','f','g','h','i','j','k','l','m','n',
  434. 'o','p','q','r','s','t','u','v','w','x','y','z' };
  435. char constarray[] = {
  436. 'b','c','d','f','g','h','j','k','l','m','n',
  437. 'p','q','r','s','t','v','w','x','y','z' };
  438. char vowelarray[] = {
  439. 'a','e','i','o','u','y' };
  440. char digitarray[] = {
  441. '0','1','2','3','4','5','6','7','8','9' };
  442. unsigned long
  443. getRandom(unsigned long max) {
  444. unsigned short data;
  445. unsigned long result;
  446. fort_GenerateRandom((unsigned char *)&data,sizeof(data));
  447. result = (unsigned long)data * max;
  448. result = result >> 16;
  449. return result;
  450. }
  451. char getLetter(void)
  452. {
  453.    return letterarray[getRandom(sizeof(letterarray))];
  454. }
  455. char getVowel(void)
  456. {
  457.    return vowelarray[getRandom(sizeof(vowelarray))];
  458. }
  459. char getDigit(void)
  460. {
  461.    return digitarray[getRandom(sizeof(digitarray))];
  462. }
  463. char getConst(void)
  464. {
  465.    return constarray[getRandom(sizeof(constarray))];
  466. }
  467. char *getPinPhrase(void)
  468. {
  469.     char * pass = PORT_ZAlloc(5);
  470.     pass[0] = getDigit();
  471.     pass[1] = getDigit();
  472.     pass[2] = getDigit();
  473.     pass[3] = getDigit();
  474.     return pass;
  475. }
  476. char *getPassPhrase(void)
  477. {
  478.     char * pass = PORT_ZAlloc(13);
  479.     pass[0] = getConst()+'A'-'a';
  480.     pass[1] = getVowel();
  481.     pass[2] = getConst();
  482.     pass[3] = getVowel();
  483.     pass[4] = getConst();
  484.     pass[5] = getVowel();
  485.     pass[6] = getConst();
  486.     pass[7] = getDigit();
  487.     pass[8] = getDigit();
  488.     pass[9] = getDigit();
  489.     pass[10] = getDigit();
  490.     pass[11] = getLetter()+'A'-'a';
  491.     return pass;
  492. }
  493. extern void
  494. makeCertSlot(fortSlotEntry *   entry,
  495. int            index,
  496. char *         label,
  497. SECItem *      cert,
  498.   FORTSkipjackKeyPtr Ks, 
  499. unsigned char *xKEA, 
  500. unsigned char *xDSA, 
  501.   unsigned char *pubKey, 
  502. int            pubKeyLen, 
  503. unsigned char *p, 
  504. unsigned char *q, 
  505. unsigned char *g);
  506. extern void
  507. makeProtectedPhrase(FORTSWFile *     file, 
  508. fortProtectedPhrase *prot_phrase,
  509.          FORTSkipjackKeyPtr   Ks, 
  510. FORTSkipjackKeyPtr   Kinit, 
  511. char *               phrase);
  512. extern void
  513. fill_in(SECItem *item, unsigned char *data, int len);
  514. char *userLabel = "INKS0002                            ";
  515. main(int argc, char **argv)
  516. {
  517. char *progname = *argv++;
  518. char *commonName = NULL;
  519. char *caname = NULL;
  520. char *email = NULL;
  521. char *outname = NULL;
  522. char *cp;
  523. int arg_count = 0;
  524. Cert caCert;
  525.         SECItem userCert;
  526. int cirv,i;
  527. int cards, start;
  528. unsigned char *subject;
  529. int            subject_len;
  530. int            signature_len = sizeof(signature);
  531. int            newSubject_len, newCertBody_len, len;
  532. int            cname1_len, cname_len, pstring_len;
  533. int            valitity_len = sizeof(valitity);
  534. unsigned char origCert[CERT_SIZE];
  535. unsigned char newSubject[CERT_SIZE];
  536. unsigned char newCertBody[CERT_SIZE];
  537. unsigned char newCert[CERT_SIZE];
  538. unsigned char pstring[CERT_SIZE];
  539. unsigned char cname1[CERT_SIZE];
  540. unsigned char cname[CERT_SIZE];
  541. CERTCertificate *myCACert = NULL;
  542. CERTCertificate *cert;
  543. CERTCertDBHandle certhandle;
  544. SECStatus rv;
  545. SECMODModule *module;
  546. unsigned char serial[16];
  547. SECKEYPublicKey *pubKey;
  548. DSAPrivateKey *keaPrivKey;
  549. DSAPrivateKey *dsaPrivKey;
  550. CI_RANDOM randomVal;
  551. PQGParams *params;
  552. int pca_index = -1;
  553. unsigned char *p,*q,*g;
  554. FORTSkipjackKey Ks;
  555. FORTSkipjackKey Kinit;
  556.         FORTSWFile *file;
  557.         FORTSignedSWFile *signed_file;
  558.         FORTSignedSWFile *signed_file2;
  559. unsigned char random[20];
  560. unsigned char vers;
  561. unsigned char *data;
  562. char *transportPin=NULL;
  563. char *ssoMemPhrase=NULL;
  564. char *userMemPhrase=NULL;
  565. char *ssoPin=NULL;
  566. char *userPin=NULL;
  567. char *pass=NULL;
  568. SECItem *outItem;
  569. int email_len = 0;
  570. int emailAVA_len = 0;
  571.    
  572.     /* put better argument parsing here */
  573.     while ((cp = *argv++) != NULL) {
  574. if (*cp == '-') {
  575.     while (*++cp) {
  576. switch (*cp) {
  577. /* verbose mode */
  578. case 'e':
  579.     email = *argv++;
  580.     break;
  581. /* explicitly set the target */
  582. case 'o':
  583.     outname = *argv++;
  584.     break;
  585. case 't':
  586. /* provide password on command line */
  587.     transportPin = *argv++;
  588.     break;
  589. case 'u':
  590. /* provide user password on command line */
  591.     userPin = *argv++;
  592.     break;
  593. case 'U':
  594. /* provide user password on command line */
  595.     userMemPhrase = *argv++;
  596.     break;
  597. case 's':
  598. /* provide user password on command line */
  599.     ssoPin = *argv++;
  600.     break;
  601. case 'S':
  602. /* provide user password on command line */
  603.     ssoMemPhrase = *argv++;
  604.     break;
  605. case 'p':
  606. /* provide card password on command line */
  607.     pass = *argv++;
  608.     break;
  609. case 'd':
  610.     transportPin="test1234567890";
  611.     ssoMemPhrase="sso1234567890";
  612.     userMemPhrase="user1234567890";
  613.     ssoPin="9999";
  614.     userPin="0000";
  615.     break;
  616. default:
  617.     usage(progname);
  618.     break;
  619. }
  620.     }
  621. } else switch (arg_count++) {
  622.     case 0:
  623. commonName = cp;
  624. break;
  625.     case 1:
  626. caname = cp;
  627. break;
  628.     default:
  629. usage(progname);
  630.     }
  631.     if (outname == NULL) outname = "swfort.sfi";
  632.     if (caname == NULL) usage(progname);
  633. caCert.card = -1;
  634. memset(newCert,0,CERT_SIZE);
  635. if (commonName == NULL) usage(progname);
  636. cirv = CI_Initialize(&cards);
  637.         start = 0;
  638. for (i=0; i < cards; i++) {
  639.     cirv = InitCard(i+1,pass);
  640.     if (cirv == CI_OK) {
  641.       if (FoundCert(i+1,caname,&caCert)) {
  642. break;
  643.       }
  644.     }
  645. }
  646.    
  647. if (caCert.card == -1) {
  648.    fprintf(stderr,
  649. "WARNING: Couldn't find Signing CA...new cert will not be signedn");
  650. }
  651. /*
  652.  * initialize enough security to deal with certificates.
  653.  */
  654. rv = CERT_OpenVolatileCertDB(&certhandle);
  655. if (rv != SECSuccess) {
  656.     Terminate("Couldn't build temparary Cert Database", 
  657. 1, -1, caCert.card);
  658.     exit(1);
  659. }
  660. CERT_SetDefaultCertDB(&certhandle);
  661. RNG_RNGInit();
  662. CI_GenerateRandom(random);
  663. RNG_RandomUpdate(random,sizeof(random));
  664. CI_GenerateRandom(random);
  665. RNG_RandomUpdate(random,sizeof(random));
  666. PK11_InitSlotLists();
  667. module = SECMOD_NewInternal();
  668. if (module == NULL) {
  669.     Terminate("Couldn't initialize security", 1, -1, caCert.card);
  670.     exit(1);
  671. }
  672. rv = SECMOD_LoadModule(module);
  673. if (rv != SECSuccess) {
  674.     Terminate("Couldn't initialize security", 2, -1, caCert.card);
  675.     exit(1);
  676. }
  677.     if (transportPin == NULL) transportPin = getPassPhrase();
  678.     if (ssoMemPhrase == NULL) ssoMemPhrase = getPassPhrase();
  679.     if (userMemPhrase == NULL) userMemPhrase = getPassPhrase();
  680.     if (ssoPin == NULL) ssoPin = getPinPhrase();
  681.     if (userPin == NULL) userPin = getPinPhrase();
  682. /* now dump the certs into the temparary data base */
  683. for (i=0; i < caCert.count; i++) {
  684.     int trusted = 0;
  685.          SECItem derCert;
  686.     cirv = CI_Select(caCert.card);
  687.     if (cirv != CI_OK) {
  688. Terminate("Couldn't select on CA card",cirv, 
  689. -1, caCert.card);
  690.     }
  691.     cirv = CI_GetCertificate(caCert.valid[i].index,origCert);
  692.             if (cirv != CI_OK) {
  693. continue;
  694.     }
  695.     derCert.data = origCert;
  696.     derCert.len = Cert_length(origCert, sizeof(origCert));
  697.     cert = CERT_NewTempCertificate(&certhandle,&derCert, NULL, 
  698. PR_FALSE, PR_TRUE);
  699.     caCert.valid[i].cert = cert;
  700.     if (cert == NULL) continue;
  701.             if (caCert.valid[i].index == caCert.index) myCACert=cert;
  702.     if (caCert.valid[i].index == atoi((char *)&caCert.label[4]))
  703.  pca_index = i;
  704. }
  705. if (myCACert == NULL) {
  706.    Terminate("Couldn't find CA's Certificate", 1, -1, caCert.card);
  707.    exit(1);
  708. }
  709.         /*
  710.  * OK now build the user cert.
  711.  */
  712. /* first get the serial number and KMID */
  713.         cirv = CI_GenerateRandom(randomVal);
  714. memcpy(&header[2],randomVal,sizeof(serial));
  715. memcpy(serial,randomVal,sizeof(serial));
  716. memcpy(&key[KEY_START+KMID_OFFSET],randomVal+sizeof(serial),7);
  717.  /* KMID */
  718. /* now generate the keys */
  719. pubKey = CERT_ExtractPublicKey(myCACert);
  720. if (pubKey == NULL) {
  721.    Terminate("Couldn't extract CA's public key", 
  722. 1, -1, caCert.card);
  723.    exit(1);
  724. }
  725. switch (pubKey->keyType) {
  726. case fortezzaKey:
  727.     params = &pubKey->u.fortezza.params;
  728.     break;
  729. case dsaKey:
  730.     params = &pubKey->u.dsa.params;
  731.     break;
  732. default:
  733.    Terminate("Certificate is not a fortezza or DSA Cert",
  734. 1, -1, caCert.card);
  735.    exit(1);
  736. }
  737. rv = DSA_NewKey(params,&keaPrivKey);
  738. if (rv != SECSuccess) {
  739.    Terminate("Couldn't Generate KEA key", 
  740. PORT_GetError(), -1, caCert.card);
  741.    exit(1);
  742. }
  743. rv = DSA_NewKey(params,&dsaPrivKey);
  744. if (rv != SECSuccess) {
  745.    Terminate("Couldn't Generate DSA key", 
  746. PORT_GetError(), -1, caCert.card);
  747.    exit(1);
  748. }
  749. if (keaPrivKey->publicValue.len == 129) 
  750. keaPrivKey->publicValue.data++;
  751. if (dsaPrivKey->publicValue.len == 129) 
  752. dsaPrivKey->publicValue.data++;
  753. if (keaPrivKey->privateValue.len == 21) 
  754. keaPrivKey->privateValue.data++;
  755. if (dsaPrivKey->privateValue.len == 21) 
  756. dsaPrivKey->privateValue.data++;
  757. /* save the parameters */
  758. p = params->prime.data;
  759. if (params->prime.len == 129) p++;
  760. q = params->subPrime.data;
  761. if (params->subPrime.len == 21) q++;
  762. g = params->base.data;
  763. if (params->base.len == 129) g++;
  764. memcpy(&key[KEY_START+KEA_OFFSET],
  765. keaPrivKey->publicValue.data,
  766. keaPrivKey->publicValue.len);
  767. memcpy(&key[KEY_START+DSA_OFFSET],
  768. dsaPrivKey->publicValue.data,
  769. dsaPrivKey->publicValue.len);
  770. /* build the der subject */
  771. subject = data_start(myCACert->derSubject.data,myCACert->derSubject.len,
  772. &subject_len);
  773. /* build the new Common name AVA */
  774. len = DER_Sequence(pstring,strlen(commonName));
  775. memcpy(pstring+len,commonName,strlen(commonName));
  776.  len += strlen(commonName);
  777. pstring_len = len;
  778. pstring[0] = 0x13;
  779. len = DER_Sequence(cname1,sizeof(cnam_oid)+pstring_len);
  780. memcpy(cname1+len,cnam_oid,sizeof(cnam_oid)); len += sizeof(cnam_oid);
  781. memcpy(cname1+len,pstring,pstring_len); len += pstring_len;
  782. cname1_len = len;
  783. len = DER_Sequence(cname, cname1_len);
  784. memcpy(cname+len,cname1,cname1_len); len += cname1_len;
  785. cname_len = len;
  786. cname[0] = 0x31; /* make it a set rather than a sequence */
  787. if (email) {
  788.     email_len = strlen(email);
  789.     emailAVA_len = EMAIL_DATA_START + email_len;
  790. }
  791. /* now assemble it */
  792. len = DER_Sequence(newSubject,subject_len + sizeof(software_ou) +
  793. cname_len + emailAVA_len);
  794. memcpy(newSubject+len,subject,subject_len);
  795. for (i=0; i < subject_len; i++) {
  796.    if (memcmp(newSubject+len+i,cnam_oid,sizeof(cnam_oid)) == 0) {
  797. newSubject[i+len+4] = 0x0b; /* change CN to OU */
  798. break;
  799.    }
  800. }
  801. len += subject_len;
  802. memcpy(newSubject+len,software_ou,sizeof(software_ou)); 
  803. len += sizeof(software_ou);
  804. memcpy(newSubject+len,cname,cname_len); len += cname_len;
  805. newSubject_len = len;
  806. /*
  807.  * build the email AVA
  808.  */
  809. if (email) {
  810.     memcpy(&emailAVA[EMAIL_DATA_START],email,email_len);
  811.     for (i=0; i < offsetCount; i++) {
  812. emailAVA[emailOffset[i]] += email_len;
  813.     }
  814.     memcpy(newSubject+len,emailAVA,emailAVA_len);
  815.     newSubject_len += emailAVA_len;
  816. }
  817. /*
  818.  * Assemble the Cert
  819.  */
  820. len = DER_Sequence(newCertBody,sizeof(header)+newSubject_len+
  821.    valitity_len+myCACert->derSubject.len+sizeof(key));
  822. memcpy(newCertBody+len,header,sizeof(header));len += sizeof(header);
  823. memcpy(newCertBody+len,myCACert->derSubject.data,
  824. myCACert->derSubject.len);len += myCACert->derSubject.len;
  825. memcpy(newCertBody+len,valitity,valitity_len);len += valitity_len;
  826. memcpy(newCertBody+len,newSubject,newSubject_len);
  827. len += newSubject_len;
  828. memcpy(newCertBody+len,key,sizeof(key));len += sizeof(key);
  829. newCertBody_len = len;
  830. /*
  831.  * generate the hash
  832.  */
  833. cirv = CI_InitializeHash();
  834. if (cirv == CI_OK) {
  835.     int hash_left = newCertBody_len & 63;
  836.     int hash_len = newCertBody_len - hash_left;
  837.     cirv = CI_Hash(hash_len,newCertBody);
  838.     if (cirv == CI_OK) {
  839. cirv = CI_GetHash(hash_left,newCertBody+hash_len,hash);
  840.     }
  841. }
  842. /*
  843.  * now sign the hash
  844.  */
  845. if ((cirv == CI_OK) && (caCert.card != -1)) {
  846.     cirv = CI_Select(caCert.card);
  847.     if (cirv == CI_OK) {
  848. cirv = CI_SetPersonality(caCert.index);
  849. if (cirv == CI_OK) {
  850.     cirv = CI_Sign(hash,sig);
  851. }
  852.     }
  853. } else cirv = -1;
  854. if (cirv != CI_OK) {
  855.    memcpy(sig,hash,sizeof(hash));
  856. }
  857. /*
  858.  * load in new signature
  859.  */
  860. {
  861.     int sig_len;
  862.     unsigned char *sig_start = 
  863. GetSignature(signature,signature_len,&sig_len);
  864.     memcpy(sig_start,sig,sizeof(sig));
  865. }
  866. /*
  867.  * now do the final wrap
  868.  */
  869. len = DER_Sequence(newCert,newCertBody_len+signature_len);
  870. memcpy(newCert+len,newCertBody,newCertBody_len); len += newCertBody_len;
  871. memcpy(newCert+len, signature, signature_len); len +=signature_len;
  872. userCert.data = newCert;
  873. userCert.len = len;
  874. /* OK, we now have our cert, let's go build our software file */
  875. signed_file = PORT_ZNew(FORTSignedSWFile);
  876. file = &signed_file->file;
  877. signed_file->signatureWrap.signature.data  = PORT_ZAlloc(40);
  878. signed_file->signatureWrap.signature.len  = 40;
  879. signed_file->signatureWrap.signatureAlgorithm.algorithm.data  =
  880.                                        fortezza_oid;
  881. signed_file->signatureWrap.signatureAlgorithm.algorithm.len = 
  882. sizeof(fortezza_oid);
  883.         vers = 1;
  884. fill_in(&file->version,&vers,1);
  885. file->derIssuer.data = myCACert->derSubject.data;
  886. file->derIssuer.len = myCACert->derSubject.len;
  887. file->serialID.data = serial;
  888. file->serialID.len =sizeof(serial);
  889. /* generate out Ks value */
  890. fort_GenerateRandom(Ks,sizeof(Ks));
  891. makeProtectedPhrase(file,&file->initMemPhrase,Kinit,NULL,transportPin);
  892. makeProtectedPhrase(file,&file->ssoMemPhrase,Ks,Kinit,ssoMemPhrase);
  893. makeProtectedPhrase(file,&file->ssoPinPhrase,Ks,Kinit,ssoPin);
  894. makeProtectedPhrase(file,&file->userMemPhrase,Ks,Kinit,userMemPhrase);
  895. makeProtectedPhrase(file,&file->userPinPhrase,Ks,Kinit,userPin);
  896. file->wrappedRandomSeed.data = PORT_ZAlloc(12);
  897. file->wrappedRandomSeed.len = 12;
  898.         cirv = fort_GenerateRandom(file->wrappedRandomSeed.data,10);
  899. if (cirv != CI_OK) {
  900.    Terminate("Couldn't get Random Seed", 
  901. cirv, -1, caCert.card);
  902. }
  903. fort_skipjackWrap(Ks,12,file->wrappedRandomSeed.data,
  904.                                 file->wrappedRandomSeed.data);
  905. file->slotEntries = PORT_ZAlloc(sizeof(fortSlotEntry *)*5);
  906. /* paa */
  907. file->slotEntries[0] = PORT_ZNew(fortSlotEntry);
  908. makeCertSlot(file->slotEntries[0],0,caCert.valid[0].label,
  909. &caCert.valid[0].cert->derCert,
  910. Ks,NULL,NULL,NULL,0,p,q,g);
  911. /* pca */
  912. file->slotEntries[1] = PORT_ZNew(fortSlotEntry);
  913. makeCertSlot(file->slotEntries[1],1,caCert.valid[pca_index].label,
  914. &caCert.valid[pca_index].cert->derCert,
  915. Ks,NULL,NULL,NULL,0,p,q,g);
  916. /* ca */
  917. file->slotEntries[2] = PORT_ZNew(fortSlotEntry);
  918. /* make sure the caCert lable points to our new pca slot location */
  919. caCert.label[4] = '0';
  920. caCert.label[5] = '0';
  921. caCert.label[6] = '0';
  922. caCert.label[7] = '1';
  923. makeCertSlot(file->slotEntries[2],2,caCert.label,&myCACert->derCert,
  924. Ks,NULL,NULL,NULL,0,p,q,g);
  925. /* user */
  926. file->slotEntries[3] = PORT_ZNew(fortSlotEntry);
  927. strncpy(&userLabel[8],commonName,sizeof(CI_PERSON)-8);
  928. makeCertSlot(file->slotEntries[3],3,userLabel,&userCert,Ks,
  929. keaPrivKey->privateValue.data,
  930. dsaPrivKey->privateValue.data,
  931. key, sizeof(key), p, q, g);
  932. file->slotEntries[4] = 0;
  933. /* encode the file so we can sign it */
  934. outItem = FORT_PutSWFile(signed_file);
  935. /* get the der encoded data to sign */
  936. signed_file2 = FORT_GetSWFile(outItem);
  937. /* now sign it */
  938. len = signed_file2->signatureWrap.data.len;
  939. data = signed_file2->signatureWrap.data.data;
  940. /*
  941.  * generate the hash
  942.  */
  943. cirv = CI_InitializeHash();
  944. if (cirv == CI_OK) {
  945.     int hash_left = len & 63;
  946.     int hash_len = len - hash_left;
  947.     cirv = CI_Hash(hash_len,data);
  948.     if (cirv == CI_OK) {
  949. cirv = CI_GetHash(hash_left,data+hash_len,hash);
  950.     }
  951. }
  952. /*
  953.  * now sign the hash
  954.  */
  955. if ((cirv == CI_OK) && (caCert.card != -1)) {
  956.     cirv = CI_Select(caCert.card);
  957.     if (cirv == CI_OK) {
  958. cirv = CI_SetPersonality(caCert.index);
  959. if (cirv == CI_OK) {
  960.     cirv = CI_Sign(hash,sig);
  961. }
  962.     }
  963. } else cirv = -1;
  964. if (cirv != CI_OK) {
  965.    memcpy(sig,hash,sizeof(hash));
  966. }
  967. memcpy( signed_file->signatureWrap.signature.data,sig,sizeof(sig));
  968. signed_file->signatureWrap.signature.len = sizeof(sig)*8; 
  969. /* encode it for the last time */
  970. outItem = FORT_PutSWFile(signed_file);
  971. /*
  972.  * write it out to the .sfi file
  973.  */
  974. {
  975.     int fd = open(outname,O_WRONLY|O_CREAT|O_BINARY,0777);
  976.     write(fd,outItem->data,outItem->len);
  977.     close(fd);
  978. }
  979. CI_Close(CI_POWER_DOWN_FLAG,caCert.card);
  980. CI_Terminate();
  981. printf("Wrote %s to file %s.n",commonName,outname);
  982. printf("Initialization Memphrase: %sn",transportPin);
  983. printf("SSO Memphrase: %sn",ssoMemPhrase);
  984. printf("User Memphrase: %sn",userMemPhrase);
  985. printf("SSO pin: %sn",ssoPin);
  986. printf("User pin: %sn",userPin);
  987. return 0;
  988. }