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 buf[0]='\0'; 69 fgets(buf,sizeof buf,stdin); 70 i=strlen(buf); 71 if (i > 0) buf[--i]='\0'; 72 if (!ASN1_STRING_set((ASN1_STRING *)spki->spkac->challenge, 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 */ 93 int EVP_PKEY_assign(pkey,type,key) 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; 136 ASN1_OBJECT_free(a->algorithm); 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(); 144 a->parameter->type=V_ASN1_NULL; 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 162