Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 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> |
Bodo Möller | ec57782 | 1999-04-23 22:13:45 +0000 | [diff] [blame] | 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> |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 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); |
Ben Laurie | 54a656e | 2002-11-13 15:43:43 +0000 | [diff] [blame^] | 68 | buf[0]='\0'; |
| 69 | fgets(buf,sizeof buf,stdin); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 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 | |