| /* NOCW */ |
| /* demos/spkigen.c |
| * 18-Mar-1997 - eay - A quick hack :-) |
| * version 1.1, it would probably help to save or load the |
| * private key :-) |
| */ |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include "err.h" |
| #include "asn1.h" |
| #include "objects.h" |
| #include "evp.h" |
| #include "x509.h" |
| #include "pem.h" |
| |
| /* The following two don't exist in SSLeay but they are in here as |
| * examples */ |
| #define PEM_write_SPKI(fp,x) \ |
| PEM_ASN1_write((int (*)())i2d_NETSCAPE_SPKI,"SPKI",fp,\ |
| (char *)x,NULL,NULL,0,NULL) |
| int SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); |
| |
| /* These are defined in the next version of SSLeay */ |
| int EVP_PKEY_assign(EVP_PKEY *pkey, int type,char *key); |
| #define RSA_F4 0x10001 |
| #define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\ |
| (char *)(rsa)) |
| |
| int main(argc,argv) |
| int argc; |
| char *argv[]; |
| { |
| RSA *rsa=NULL; |
| NETSCAPE_SPKI *spki=NULL; |
| EVP_PKEY *pkey=NULL; |
| char buf[128]; |
| int ok=0,i; |
| FILE *fp; |
| |
| pkey=EVP_PKEY_new(); |
| |
| if (argc < 2) |
| { |
| /* Generate an RSA key, the random state should have been seeded |
| * with lots of calls to RAND_seed(....) */ |
| fprintf(stderr,"generating RSA key, could take some time...\n"); |
| if ((rsa=RSA_generate_key(512,RSA_F4,NULL)) == NULL) goto err; |
| } |
| else |
| { |
| if ((fp=fopen(argv[1],"r")) == NULL) |
| { perror(argv[1]); goto err; } |
| if ((rsa=PEM_read_RSAPrivateKey(fp,NULL,NULL)) == NULL) |
| goto err; |
| fclose(fp); |
| } |
| |
| if (!EVP_PKEY_assign_RSA(pkey,rsa)) goto err; |
| rsa=NULL; |
| |
| /* lets make the spki and set the public key and challenge */ |
| if ((spki=NETSCAPE_SPKI_new()) == NULL) goto err; |
| |
| if (!SPKI_set_pubkey(spki,pkey)) goto err; |
| |
| fprintf(stderr,"please enter challenge string:"); |
| fflush(stderr); |
| fgets(buf,120,stdin); |
| i=strlen(buf); |
| if (i > 0) buf[--i]='\0'; |
| if (!ASN1_STRING_set((ASN1_STRING *)spki->spkac->challenge, |
| buf,i)) goto err; |
| |
| if (!NETSCAPE_SPKI_sign(spki,pkey,EVP_md5())) goto err; |
| PEM_write_SPKI(stdout,spki); |
| if (argc < 2) |
| PEM_write_RSAPrivateKey(stdout,pkey->pkey.rsa,NULL,NULL,0,NULL); |
| |
| ok=1; |
| err: |
| if (!ok) |
| { |
| fprintf(stderr,"something bad happened...."); |
| ERR_print_errors_fp(stderr); |
| } |
| NETSCAPE_SPKI_free(spki); |
| EVP_PKEY_free(pkey); |
| exit(!ok); |
| } |
| |
| /* This function is in the next version of SSLeay */ |
| int EVP_PKEY_assign(pkey,type,key) |
| EVP_PKEY *pkey; |
| int type; |
| char *key; |
| { |
| if (pkey == NULL) return(0); |
| if (pkey->pkey.ptr != NULL) |
| { |
| if (pkey->type == EVP_PKEY_RSA) |
| RSA_free(pkey->pkey.rsa); |
| /* else memory leak */ |
| } |
| pkey->type=type; |
| pkey->pkey.ptr=key; |
| return(1); |
| } |
| |
| /* While I have a |
| * X509_set_pubkey() and X509_REQ_set_pubkey(), SPKI_set_pubkey() does |
| * not currently exist so here is a version of it. |
| * The next SSLeay release will probably have |
| * X509_set_pubkey(), |
| * X509_REQ_set_pubkey() and |
| * NETSCAPE_SPKI_set_pubkey() |
| * as macros calling the same function */ |
| int SPKI_set_pubkey(x,pkey) |
| NETSCAPE_SPKI *x; |
| EVP_PKEY *pkey; |
| { |
| int ok=0; |
| X509_PUBKEY *pk; |
| X509_ALGOR *a; |
| ASN1_OBJECT *o; |
| unsigned char *s,*p; |
| int i; |
| |
| if (x == NULL) return(0); |
| |
| if ((pk=X509_PUBKEY_new()) == NULL) goto err; |
| a=pk->algor; |
| |
| /* set the algorithm id */ |
| if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err; |
| ASN1_OBJECT_free(a->algorithm); |
| a->algorithm=o; |
| |
| /* Set the parameter list */ |
| if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL)) |
| { |
| ASN1_TYPE_free(a->parameter); |
| a->parameter=ASN1_TYPE_new(); |
| a->parameter->type=V_ASN1_NULL; |
| } |
| i=i2d_PublicKey(pkey,NULL); |
| if ((s=(unsigned char *)malloc(i+1)) == NULL) goto err; |
| p=s; |
| i2d_PublicKey(pkey,&p); |
| if (!ASN1_BIT_STRING_set(pk->public_key,s,i)) goto err; |
| free(s); |
| |
| X509_PUBKEY_free(x->spkac->pubkey); |
| x->spkac->pubkey=pk; |
| pk=NULL; |
| ok=1; |
| err: |
| if (pk != NULL) X509_PUBKEY_free(pk); |
| return(ok); |
| } |
| |