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