OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
spkigen.c
Go to the documentation of this file.
1 /* NOCW */
2 /* demos/spkigen.c
3  * 18-Mar-1997 - eay - A quick hack :-)
4  * version 1.1, it would probably help to save or load the
5  * private key :-)
6  */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <openssl/err.h>
10 #include <openssl/asn1.h>
11 #include <openssl/objects.h>
12 #include <openssl/evp.h>
13 #include <openssl/x509.h>
14 #include <openssl/pem.h>
15 
16 /* The following two don't exist in SSLeay but they are in here as
17  * examples */
18 #define PEM_write_SPKI(fp,x) \
19  PEM_ASN1_write((int (*)())i2d_NETSCAPE_SPKI,"SPKI",fp,\
20  (char *)x,NULL,NULL,0,NULL)
22 
23 /* These are defined in the next version of SSLeay */
24 int EVP_PKEY_assign(EVP_PKEY *pkey, int type,char *key);
25 #define RSA_F4 0x10001
26 #define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
27  (char *)(rsa))
28 
29 int main(argc,argv)
30 int argc;
31 char *argv[];
32  {
33  RSA *rsa=NULL;
34  NETSCAPE_SPKI *spki=NULL;
35  EVP_PKEY *pkey=NULL;
36  char buf[128];
37  int ok=0,i;
38  FILE *fp;
39 
40  pkey=EVP_PKEY_new();
41 
42  if (argc < 2)
43  {
44  /* Generate an RSA key, the random state should have been seeded
45  * with lots of calls to RAND_seed(....) */
46  fprintf(stderr,"generating RSA key, could take some time...\n");
47  if ((rsa=RSA_generate_key(512,RSA_F4,NULL)) == NULL) goto err;
48  }
49  else
50  {
51  if ((fp=fopen(argv[1],"r")) == NULL)
52  { perror(argv[1]); goto err; }
53  if ((rsa=PEM_read_RSAPrivateKey(fp,NULL,NULL)) == NULL)
54  goto err;
55  fclose(fp);
56  }
57 
58  if (!EVP_PKEY_assign_RSA(pkey,rsa)) goto err;
59  rsa=NULL;
60 
61  /* lets make the spki and set the public key and challenge */
62  if ((spki=NETSCAPE_SPKI_new()) == NULL) goto err;
63 
64  if (!SPKI_set_pubkey(spki,pkey)) goto err;
65 
66  fprintf(stderr,"please enter challenge string:");
67  fflush(stderr);
68  buf[0]='\0';
69  fgets(buf,sizeof buf,stdin);
70  i=strlen(buf);
71  if (i > 0) buf[--i]='\0';
73  buf,i)) goto err;
74 
75  if (!NETSCAPE_SPKI_sign(spki,pkey,EVP_md5())) goto err;
76  PEM_write_SPKI(stdout,spki);
77  if (argc < 2)
78  PEM_write_RSAPrivateKey(stdout,pkey->pkey.rsa,NULL,NULL,0,NULL);
79 
80  ok=1;
81 err:
82  if (!ok)
83  {
84  fprintf(stderr,"something bad happened....");
85  ERR_print_errors_fp(stderr);
86  }
87  NETSCAPE_SPKI_free(spki);
88  EVP_PKEY_free(pkey);
89  exit(!ok);
90  }
91 
92 /* This function is in the next version of SSLeay */
94 EVP_PKEY *pkey;
95 int type;
96 char *key;
97  {
98  if (pkey == NULL) return(0);
99  if (pkey->pkey.ptr != NULL)
100  {
101  if (pkey->type == EVP_PKEY_RSA)
102  RSA_free(pkey->pkey.rsa);
103  /* else memory leak */
104  }
105  pkey->type=type;
106  pkey->pkey.ptr=key;
107  return(1);
108  }
109 
110 /* While I have a
111  * X509_set_pubkey() and X509_REQ_set_pubkey(), SPKI_set_pubkey() does
112  * not currently exist so here is a version of it.
113  * The next SSLeay release will probably have
114  * X509_set_pubkey(),
115  * X509_REQ_set_pubkey() and
116  * NETSCAPE_SPKI_set_pubkey()
117  * as macros calling the same function */
118 int SPKI_set_pubkey(x,pkey)
119 NETSCAPE_SPKI *x;
120 EVP_PKEY *pkey;
121  {
122  int ok=0;
123  X509_PUBKEY *pk;
124  X509_ALGOR *a;
125  ASN1_OBJECT *o;
126  unsigned char *s,*p;
127  int i;
128 
129  if (x == NULL) return(0);
130 
131  if ((pk=X509_PUBKEY_new()) == NULL) goto err;
132  a=pk->algor;
133 
134  /* set the algorithm id */
135  if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
137  a->algorithm=o;
138 
139  /* Set the parameter list */
140  if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL))
141  {
142  ASN1_TYPE_free(a->parameter);
143  a->parameter=ASN1_TYPE_new();
145  }
146  i=i2d_PublicKey(pkey,NULL);
147  if ((s=(unsigned char *)malloc(i+1)) == NULL) goto err;
148  p=s;
149  i2d_PublicKey(pkey,&p);
150  if (!ASN1_BIT_STRING_set(pk->public_key,s,i)) goto err;
151  free(s);
152 
153  X509_PUBKEY_free(x->spkac->pubkey);
154  x->spkac->pubkey=pk;
155  pk=NULL;
156  ok=1;
157 err:
158  if (pk != NULL) X509_PUBKEY_free(pk);
159  return(ok);
160  }
161