1From ssl-lists-owner@mincom.com Mon Sep 30 22:43:15 1996 2Received: 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 4Received: (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) 5Received: 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) 6Received: 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 8Date: Mon, 30 Sep 1996 12:43:15 +1000 (EST) 9From: Eric Young <eay@mincom.com> 10X-Sender: eay@orb 11To: Sampo Kellomaki <sampo@neuronio.pt> 12Cc: ssl-users@mincom.com, sampo@brutus.neuronio.pt 13Subject: Re: Signing with envelope routines 14In-Reply-To: <199609300037.BAA08729@brutus.neuronio.pt> 15Message-Id: <Pine.SOL.3.91.960930121504.11800Y-100000@orb> 16Mime-Version: 1.0 17Content-Type: TEXT/PLAIN; charset=US-ASCII 18Sender: ssl-lists-owner@mincom.com 19Precedence: bulk 20Status: O 21X-Status: 22 23 24On 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 31hmm... 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 42What 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); */ 46Then 47 EVP_PKEY *pkey=X509_extract_key(x509); 48 49There is also a X509_REQ_extract_key(req); 50which gets the public key from a certificate request. 51 52I re-worked quite a bit of this when I cleaned up the dependancy on 53RSA 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 62standard such as PKCS#8 to store the private key so that the type is 63encoded 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 69The actual public key is kept in the certificate, so basically you have 70to load the certificate and then 'unpack' the public key from the 71certificate. 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 78but what I really need to do is do quite a few 'this is how you do xyz' 79type documents. I suppose the current method is to post to ssl-users and 80I'll respond :-). 81 82I'll add a 'demo' directory for the next release, I've appended a 83modified version of your program that works, you were very close :-). 84 85eric 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 101void 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 171