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]