mirror of https://github.com/openssl/openssl.git
				
				
				
			
		
			
				
	
	
		
			172 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
| /* 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 <openssl/err.h>
 | |
| #include <openssl/asn1.h>
 | |
| #include <openssl/objects.h>
 | |
| #include <openssl/evp.h>
 | |
| #include <openssl/x509.h>
 | |
| #include <openssl/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);
 | |
|     buf[0] = '\0';
 | |
|     fgets(buf, sizeof buf, 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:
 | |
|     X509_PUBKEY_free(pk);
 | |
|     return (ok);
 | |
| }
 |