]>
Commit | Line | Data |
---|---|---|
d02b48c6 RE |
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> | |
ec577822 BM |
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> | |
d02b48c6 RE |
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 |