This change was a quick experiment that I'd wanted to try that works quite
[openssl.git] / demos / spkigen.c
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)
21 int SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
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         fgets(buf,120,stdin);
69         i=strlen(buf);
70         if (i > 0) buf[--i]='\0';
71         if (!ASN1_STRING_set((ASN1_STRING *)spki->spkac->challenge,
72                 buf,i)) goto err;
73
74         if (!NETSCAPE_SPKI_sign(spki,pkey,EVP_md5())) goto err;
75         PEM_write_SPKI(stdout,spki);
76         if (argc < 2)
77                 PEM_write_RSAPrivateKey(stdout,pkey->pkey.rsa,NULL,NULL,0,NULL);
78
79         ok=1;
80 err:
81         if (!ok)
82                 {
83                 fprintf(stderr,"something bad happened....");
84                 ERR_print_errors_fp(stderr);
85                 }
86         NETSCAPE_SPKI_free(spki);
87         EVP_PKEY_free(pkey);
88         exit(!ok);
89         }
90
91 /* This function is in the next version of SSLeay */
92 int EVP_PKEY_assign(pkey,type,key)
93 EVP_PKEY *pkey;
94 int type;
95 char *key;
96         {
97         if (pkey == NULL) return(0);
98         if (pkey->pkey.ptr != NULL)
99                 {
100                 if (pkey->type == EVP_PKEY_RSA)
101                         RSA_free(pkey->pkey.rsa);
102                 /* else memory leak */
103                 }
104         pkey->type=type;
105         pkey->pkey.ptr=key;
106         return(1);
107         }
108
109 /* While I have a 
110  * X509_set_pubkey() and X509_REQ_set_pubkey(), SPKI_set_pubkey() does
111  * not currently exist so here is a version of it.
112  * The next SSLeay release will probably have
113  * X509_set_pubkey(),
114  * X509_REQ_set_pubkey() and
115  * NETSCAPE_SPKI_set_pubkey()
116  * as macros calling the same function */
117 int SPKI_set_pubkey(x,pkey)
118 NETSCAPE_SPKI *x;
119 EVP_PKEY *pkey;
120         {
121         int ok=0;
122         X509_PUBKEY *pk;
123         X509_ALGOR *a;
124         ASN1_OBJECT *o;
125         unsigned char *s,*p;
126         int i;
127
128         if (x == NULL) return(0);
129
130         if ((pk=X509_PUBKEY_new()) == NULL) goto err;
131         a=pk->algor;
132
133         /* set the algorithm id */
134         if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
135         ASN1_OBJECT_free(a->algorithm);
136         a->algorithm=o;
137
138         /* Set the parameter list */
139         if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL))
140                 {
141                 ASN1_TYPE_free(a->parameter);
142                 a->parameter=ASN1_TYPE_new();
143                 a->parameter->type=V_ASN1_NULL;
144                 }
145         i=i2d_PublicKey(pkey,NULL);
146         if ((s=(unsigned char *)malloc(i+1)) == NULL) goto err;
147         p=s;
148         i2d_PublicKey(pkey,&p);
149         if (!ASN1_BIT_STRING_set(pk->public_key,s,i)) goto err;
150         free(s);
151
152         X509_PUBKEY_free(x->spkac->pubkey);
153         x->spkac->pubkey=pk;
154         pk=NULL;
155         ok=1;
156 err:
157         if (pk != NULL) X509_PUBKEY_free(pk);
158         return(ok);
159         }
160