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