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