
1: From ssl-lists-owner@mincom.com Mon Sep 30 22:43:15 1996 2: Received: from cygnus.mincom.oz.au by orb.mincom.oz.au with SMTP id AA12802 3: (5.65c/IDA-1.4.4 for eay); Mon, 30 Sep 1996 12:45:43 +1000 4: Received: (from daemon@localhost) by cygnus.mincom.oz.au (8.7.5/8.7.3) id MAA25922 for ssl-users-outgoing; Mon, 30 Sep 1996 12:43:43 +1000 (EST) 5: Received: from orb.mincom.oz.au (eay@orb.mincom.oz.au [192.55.197.1]) by cygnus.mincom.oz.au (8.7.5/8.7.3) with SMTP id MAA25900 for <ssl-users@listserv.mincom.oz.au>; Mon, 30 Sep 1996 12:43:39 +1000 (EST) 6: Received: by orb.mincom.oz.au id AA12688 7: (5.65c/IDA-1.4.4 for ssl-users@listserv.mincom.oz.au); Mon, 30 Sep 1996 12:43:16 +1000 8: Date: Mon, 30 Sep 1996 12:43:15 +1000 (EST) 9: From: Eric Young <eay@mincom.com> 10: X-Sender: eay@orb 11: To: Sampo Kellomaki <sampo@neuronio.pt> 12: Cc: ssl-users@mincom.com, sampo@brutus.neuronio.pt 13: Subject: Re: Signing with envelope routines 14: In-Reply-To: <199609300037.BAA08729@brutus.neuronio.pt> 15: Message-Id: <Pine.SOL.3.91.960930121504.11800Y-100000@orb> 16: Mime-Version: 1.0 17: Content-Type: TEXT/PLAIN; charset=US-ASCII 18: Sender: ssl-lists-owner@mincom.com 19: Precedence: bulk 20: Status: O 21: X-Status: 22: 23: 24: On Mon, 30 Sep 1996, Sampo Kellomaki wrote: 25: > I have been trying to figure out how to produce signatures with EVP_ 26: > routines. I seem to be able to read in private key and sign some 27: > data ok, but I can't figure out how I am supposed to read in 28: > public key so that I could verify my signature. I use self signed 29: > certificate. 30: 31: hmm... a rather poorly documented are of the library at this point in time. 32: 33: > I figured I should use 34: > EVP_PKEY* pkey = PEM_ASN1_read(d2i_PrivateKey, PEM_STRING_EVP_PKEY, 35: > fp, NULL, NULL); 36: > to read in private key and this seems to work Ok. 37: > 38: > However when I try analogous 39: > EVP_PKEY* pkey = PEM_ASN1_read(d2i_PublicKey, PEM_STRING_X509, 40: > fp, NULL, NULL); 41: 42: What you should do is 43: X509 *x509=PEM_read_X509(fp,NULL,NULL); 44: /* which is the same as PEM_ASN1_read(d2i_X509,PEM_STRING_X509,fp, 45: * NULL,NULL); */ 46: Then 47: EVP_PKEY *pkey=X509_extract_key(x509); 48: 49: There is also a X509_REQ_extract_key(req); 50: which gets the public key from a certificate request. 51: 52: I re-worked quite a bit of this when I cleaned up the dependancy on 53: RSA as the private key. 54: 55: > I figured that the second argument to PEM_ASN1_read should match the 56: > name in my PEM encoded object, hence PEM_STRING_X509. 57: > PEM_STRING_EVP_PKEY seems to be somehow magical 58: > because it matches whatever private key there happens to be. I could 59: > not find a similar constant to use with getting the certificate, however. 60: 61: :-), PEM_STRING_EVP_PKEY is 'magical' :-). In theory I should be using a 62: standard such as PKCS#8 to store the private key so that the type is 63: encoded in the asn.1 encoding of the object. 64: 65: > Is my approach of using PEM_ASN1_read correct? What should I pass in 66: > as name? Can I use normal (or even self signed) X509 certificate for 67: > verifying the signature? 68: 69: The actual public key is kept in the certificate, so basically you have 70: to load the certificate and then 'unpack' the public key from the 71: certificate. 72: 73: > When will SSLeay documentation be written ;-)? If I would contribute 74: > comments to the code, would Eric take time to review them and include 75: > them in distribution? 76: 77: :-) After SSLv3 and PKCS#7 :-). I actually started doing a function list 78: but what I really need to do is do quite a few 'this is how you do xyz' 79: type documents. I suppose the current method is to post to ssl-users and 80: I'll respond :-). 81: 82: I'll add a 'demo' directory for the next release, I've appended a 83: modified version of your program that works, you were very close :-). 84: 85: eric 86: 87: /* sign-it.cpp - Simple test app using SSLeay envelopes to sign data 88: 29.9.1996, Sampo Kellomaki <sampo@iki.fi> */ 89: 90: /* converted to C - eay :-) */ 91: 92: #include <stdio.h> 93: #include "rsa.h" 94: #include "evp.h" 95: #include "objects.h" 96: #include "x509.h" 97: #include "err.h" 98: #include "pem.h" 99: #include "ssl.h" 100: 101: void main () 102: { 103: int err; 104: int sig_len; 105: unsigned char sig_buf [4096]; 106: static char certfile[] = "plain-cert.pem"; 107: static char keyfile[] = "plain-key.pem"; 108: static char data[] = "I owe you..."; 109: EVP_MD_CTX md_ctx; 110: EVP_PKEY * pkey; 111: FILE * fp; 112: X509 * x509; 113: 114: /* Just load the crypto library error strings, 115: * SSL_load_error_strings() loads the crypto AND the SSL ones */ 116: /* SSL_load_error_strings();*/ 117: ERR_load_crypto_strings(); 118: 119: /* Read private key */ 120: 121: fp = fopen (keyfile, "r"); if (fp == NULL) exit (1); 122: pkey = (EVP_PKEY*)PEM_ASN1_read ((char *(*)())d2i_PrivateKey, 123: PEM_STRING_EVP_PKEY, 124: fp, 125: NULL, NULL); 126: if (pkey == NULL) { ERR_print_errors_fp (stderr); exit (1); } 127: fclose (fp); 128: 129: /* Do the signature */ 130: 131: EVP_SignInit (&md_ctx, EVP_md5()); 132: EVP_SignUpdate (&md_ctx, data, strlen(data)); 133: sig_len = sizeof(sig_buf); 134: err = EVP_SignFinal (&md_ctx, 135: sig_buf, 136: &sig_len, 137: pkey); 138: if (err != 1) { ERR_print_errors_fp (stderr); exit (1); } 139: EVP_PKEY_free (pkey); 140: 141: /* Read public key */ 142: 143: fp = fopen (certfile, "r"); if (fp == NULL) exit (1); 144: x509 = (X509 *)PEM_ASN1_read ((char *(*)())d2i_X509, 145: PEM_STRING_X509, 146: fp, NULL, NULL); 147: if (x509 == NULL) { ERR_print_errors_fp (stderr); exit (1); } 148: fclose (fp); 149: 150: /* Get public key - eay */ 151: pkey=X509_extract_key(x509); 152: if (pkey == NULL) { ERR_print_errors_fp (stderr); exit (1); } 153: 154: /* Verify the signature */ 155: 156: EVP_VerifyInit (&md_ctx, EVP_md5()); 157: EVP_VerifyUpdate (&md_ctx, data, strlen((char*)data)); 158: err = EVP_VerifyFinal (&md_ctx, 159: sig_buf, 160: sig_len, 161: pkey); 162: if (err != 1) { ERR_print_errors_fp (stderr); exit (1); } 163: EVP_PKEY_free (pkey); 164: printf ("Signature Verified Ok.\n"); 165: } 166: 167: 168: 169: 170: