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