OpenSSL Developers - Here's a useful little hack I consed up this morning when confronted yet again with the question "Is this really the correct private key file that goes with the certificate I'm trying to use (or have I lost the #@$&*% private key file yet again)" ... :) It even seems to work. Or at least, when I give it the right private key, it's happy. And when I give it the wrong private key, it's unhappy in the right sort of way. TT #include <stdio.h> #include <stdlib.h> #include <string.h> #include "err.h" #include "evp.h" #include "rand.h" #include "x509.h" #include "x509v3.h" #include "pem.h" static char* usage[]={ "usage: vericert\n", " -cert file certificate file (x509 or pkcs7), required\n", " -key file key file, required\n", " -pass string passphrase, optional\n", NULL }; static char* passphrase; static X509* getcert(char* file) { FILE* fp; X509* cert = NULL; STACK* sk = NULL; PKCS7 *pk7 = NULL; if ((fp = fopen(file, "rb")) == NULL) { fprintf(stderr, "failed to open file %s\n", file); goto err; } pk7 = PEM_read_PKCS7(fp, NULL, NULL); fclose(fp); fp = NULL; if (pk7) { if (!PKCS7_type_is_signed(pk7)) { fprintf(stderr, "pkcs7 file %s is not pkcs7 signed type\n", file); goto err; } cert = (X509*)sk_value(pk7->d.sign->cert,sk_num(pk7->d.sign->cert)-1); if (!(cert = X509_dup(cert))) { ERR_print_errors_fp(stderr); fprintf(stderr, "trying to duplicate cert from pkcs7 file %s\n", file); goto err; } PKCS7_free(pk7); } else { if ((fp = fopen(file, "rb")) == NULL) { fprintf(stderr, "failed to open file %s\n", file); goto err; } cert = PEM_read_X509(fp, NULL, NULL); fclose(fp); fp = NULL; } if (!cert) { ERR_print_errors_fp(stderr); fprintf(stderr, "trying to read cert in %s\n", file); goto err; } return cert; err: return NULL; } static int key_callback(char *buf, int len, int verify) { int i; if (passphrase == NULL) return(0); i=strlen(passphrase); i=(i > len)?len:i; memcpy(buf,passphrase,i); return(i); } static EVP_PKEY* getkey(char* file) { FILE* fp; EVP_PKEY *k = NULL; if ((fp = fopen(file, "rb")) == NULL) { fprintf(stderr, "failed to open file %s\n", file); goto err; } k = PEM_read_PrivateKey(fp, NULL, (passphrase) ? key_callback : NULL); fclose(fp); if (!k) { ERR_print_errors_fp(stderr); fprintf(stderr, "trying to read private key\n"); goto err; } return k; err: return NULL; } int main(int argc, char **argv) { unsigned char bytes[1024], sig[1024]; char* cfile=NULL,* kfile=NULL,** pp; unsigned int len; int badops=0; EVP_MD_CTX ctx; EVP_PKEY* privkey,* pubkey; X509* cert; argc--; argv++; while (argc >= 1) { if (strcmp(*argv,"-cert") == 0) { if (--argc < 1) goto bad; cfile = *(++argv); } else if (strcmp(*argv,"-key") == 0) { if (--argc < 1) goto bad; kfile = *(++argv); } else if (strcmp(*argv,"-pass") == 0) { if (--argc < 1) goto bad; passphrase = *(++argv); } else { bad: fprintf(stderr,"unknown option %s\n",*argv); badops=1; break; } argc--; argv++; } if (badops || !cfile || !kfile) { for (pp=usage; (*pp != NULL); pp++) fprintf(stderr,*pp); goto err; } if (!cfile) { badops++; fprintf(stderr, "Error, missing required argument -cert\n"); } if (!kfile) { badops++; fprintf(stderr, "Error, missing required argument -key\n"); } if (badops) goto err; #ifdef WINDOWS RAND_screen(); #endif SSLeay_add_all_algorithms(); if (!(cert = getcert(cfile))) goto err; if (!(pubkey = X509_PUBKEY_get(X509_get_X509_PUBKEY(cert)))) { ERR_print_errors_fp(stderr); fprintf(stderr, "trying to get public key out of certificate\n"); goto err; } X509_free(cert); if (!(privkey = getkey(kfile))) goto err; RAND_bytes(bytes, sizeof(bytes)); len = EVP_PKEY_size(privkey); EVP_SignInit(&ctx, EVP_sha1()); EVP_SignUpdate(&ctx, bytes, sizeof bytes); if (!EVP_SignFinal(&ctx, sig, &len, privkey)){ ERR_print_errors_fp(stderr); fprintf(stderr, "trying to sign input\n"); goto err; } EVP_VerifyInit(&ctx,EVP_sha1()); EVP_VerifyUpdate(&ctx, bytes, sizeof bytes); if (EVP_VerifyFinal(&ctx, sig, len, pubkey) <= 0) { ERR_print_errors_fp(stderr); fprintf(stderr, "trying to verify input\n"); goto err; } fprintf(stdout, "ok\n"); return 1; err: return 0; } ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]