Hello!
Thank you both Richard and Mark. Having stored (a CA-cert, a cert
certified by the CA-cert, some data, and a signature of the data using
the cert), I wanted to verify that I really did store all of this
correctly. (clearly I do not store multiple copies of the certs). A
4-tuple like the one above will be used as proof of reception of a
command (data).
My "checking code" below seems to work now (sorry for posting more code,
but I really like to find code myself when searching the archives :-).
But I still have some conceptual gaps regarding how this works:
1) In apps/verify.c this function is used, what is the _purpose_ of it?
X509_STORE_CTX_set_purpose(csc, purpose);
2) Correct me if I am wrong but the idea is thus:
X509_STORE contains all trusted certs
X509_STORE_CTX is used only once after each initialization
X509_STORE_add_cert(ctx, CAx509);
explicitly adds CAx509 as a cacert to be trusted
X509_STORE_CTX_init(&csc, ctx, x509, NULL);
Says that we want to verify the cert x509 using the trusted certs in the
store csc
Still missing here is what the last parameter is supposed to accomplish?
Is that for the case that we have a cacert chain with a root contained
in csc?
X509_verify_cert(&csc);
Does the actual traversal
3) Under what circumstances is the callback called and what happens when
it is set to NULL like below:
X509_STORE_set_verify_cb_func(ctx, NULL);
Thank you for your help.
/Douglas
#include <stdarg.h>
#include <stdio.h>
#define USE_SOCKETS
#define MAX_HTTP_BUF_SIZE 8*1024
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <openssl/e_os.h>
#include <openssl/bn.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/evp.h>
int
main(int argc, char *argv[]) {
EVP_MD_CTX md_ctx;
EVP_PKEY *pkey;
char buf[4096];
char *bufp;
int n, len;
X509 *cert;
X509 *cacert;
FILE *fp;
X509_STORE *ctx = NULL;
X509_STORE_CTX *csc;
if (argc != 5) {
printf("Usage: %s <cacert> <cert> <data> <signature>\n", argv[0]);
exit(1);
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "Failed to open cacert file!\n");
exit(1);
}
cacert = PEM_read_X509(fp, NULL, NULL, NULL);
if (cacert == NULL) {
fprintf(stderr, "Failed to read cacert from certfile!\n");
exit(1);
}
fclose(fp);
fp = fopen(argv[2], "r");
if (fp == NULL) {
fprintf(stderr, "Failed to open certfile!\n");
exit(1);
}
cert = PEM_read_X509(fp, NULL, NULL, NULL);
if (cert == NULL) {
fprintf(stderr, "Failed to read cert from certfile!\n");
exit(1);
}
fclose(fp);
ERR_load_crypto_strings();
SSL_library_init();
ctx = X509_STORE_new();
X509_STORE_set_verify_cb_func(ctx, NULL);
X509_STORE_add_cert(ctx, cacert);
csc = X509_STORE_CTX_new();
if (csc == NULL) {
fprintf(stderr, "Failed to create store!\n");
ERR_print_errors_fp(stderr);
exit(1);
}
X509_STORE_CTX_init(csc, ctx, cert, NULL);
if (!X509_verify_cert(csc)) {
fprintf(stderr, "Verification of cert failed!\n");
exit(1);
}
X509_STORE_CTX_free(csc);
X509_STORE_free(ctx);
pkey = X509_get_pubkey(cert);
if (pkey == NULL) {
fprintf(stderr, "Failed to extract public key from cert!\n");
exit(1);
}
fp = fopen(argv[3], "r");
if (fp == NULL) {
fprintf(stderr, "Failed to open data file!\n");
exit(1);
}
EVP_VerifyInit(&md_ctx, EVP_sha1());
while (!feof(fp)) {
n = fread(buf, 1, 4096, fp);
EVP_VerifyUpdate(&md_ctx, buf, n);
}
fclose(fp);
fp = fopen(argv[4], "r");
if (fp == NULL) {
fprintf(stderr, "Failed to open signature file!\n");
exit(1);
}
bufp = buf;
len = 0;
while(!feof(fp)) {
n = fread(bufp, 1, 4096, fp);
len += n;
bufp += n;
}
n = EVP_VerifyFinal(&md_ctx, buf, len, pkey);
if (n != 1) {
fprintf(stderr, "Invalid signature for data!\n");
} else {
printf("The CA-cert, cert, data and signature are consistent!\n");
}
X509_free(cacert);
X509_free(cert);
return 0;
}
mark schoneman wrote:
>
> #ifdef __cplusplus
> extern "C" {
> #endif
>
> #include <stdio.h>
> #include <stdlib.h>
>
> #include "openssl/buffer.h"
> #include "openssl/crypto.h"
> #include "openssl/objects.h"
> #include "openssl/asn1.h"
> #include "openssl/evp.h"
> #include "openssl/err.h"
> #include "openssl/x509.h"
> #include "openssl/pem.h"
> #include "openssl/pkcs12.h"
>
> X509 *x509=NULL;
> X509 *CAx509=NULL;
> EVP_PKEY *CApkey=NULL;
> PKCS12 *p12=NULL;
> BIO *bio_err;
> static int cb(int ok, X509_STORE_CTX *ctx);
>
> int main()
> {
> FILE *fp, fp1;
> char *path = "/home/mschonem/cert.pem";
> char *path1 = "/home/mschonem/key.pem";
> char *path2 = "/home/mschonem/test.p12";
> char *path3 = "/home/mschonem/test1.p12";
> char *pathca = "/d0/devo/CA/lib/cacert.pem";
> char *pathcakey = "/d0/devo/CA/lib/private/cakey.pem";
>
> char buffer[4096];
>
> int i, ret, j=0, k=0;
> int len, status;
>
> X509_STORE *ctx=NULL;
> X509_STORE_CTX csc;
>
> Init_CryptoLib();
> ERR_load_crypto_strings();
>
> SSLeay_add_all_algorithms();
>
> fp = fopen(pathca, "r");
> i = fread(buffer, 1, 4096, fp);
> fclose(fp);
>
> Get_Cert_fp(buffer, &CAx509); /*Get CA Certificate */
>
> fp = fopen(path, "r");
> i = fread(buffer, 1, 4096, fp);
> fclose(fp);
>
> Get_Cert_fp(buffer, &x509);
>
> ctx = X509_STORE_new();
>
> X509_STORE_set_verify_cb_func(ctx,cb);
>
> status = X509_STORE_set_default_paths(ctx);
> printf("Status %d\n", status);
> status = X509_STORE_add_cert(ctx, CAx509);
> printf("Status %d\n", status);
> X509_STORE_CTX_init(&csc, ctx, x509, NULL);
> status = X509_verify_cert(&csc);
>
> end:
>
> if (!status){
> printf("Verify error %d at %d depth lookup:%s\n",csc.error,
> csc.error_depth,
> X509_verify_cert_error_string(csc.error));
> status = csc.error;
> } else status = 0;
>
> X509_STORE_CTX_free(&csc);
>
> if (x509 != NULL) X509_free(x509);
>
> printf("%d \n",csc.error);
> return(status);
>
> }
>
> static int cb(int ok, X509_STORE_CTX *ctx)
> {
> char buf[256];
>
> if (!ok)
> {
> X509_NAME_oneline(
>
> X509_get_subject_name(ctx->current_cert),buf,256);
> printf("%s\n",buf);
> printf("error %d at %d depth lookup:%s\n",ctx->error,
> ctx->error_depth,
> X509_verify_cert_error_string(ctx->error));
> if (ctx->error == X509_V_ERR_CERT_HAS_EXPIRED) ok=1;
> /* since we are just checking the certificates, it is
> * ok if they are self signed. But we should still warn
> * the user.
> */
> if (ctx->error ==
> X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ok=1;
> /* Continue after extension errors too */
> if (ctx->error == X509_V_ERR_INVALID_CA) ok=1;
> if (ctx->error == X509_V_ERR_PATH_LENGTH_EXCEEDED) ok=1;
> if (ctx->error == X509_V_ERR_INVALID_PURPOSE) ok=1;
> if (ctx->error ==
> X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ok=1;
> }
>
> ERR_clear_error();
> return(ok);
> }
>
> static int Get_Cert_fp(char *buffer, X509 *cert)
> {
> BIO *bio_err = NULL;
> BIO *in=NULL;
> BUF_MEM *bm = NULL;
>
> int ok= -1,i;
>
> if(bio_err == NULL){
> if ((bio_err=BIO_new(BIO_s_file())) != NULL)
> BIO_set_fp(bio_err,stderr,BIO_NOCLOSE);
> }
>
>
> in=BIO_new(BIO_s_mem());
> bm = BUF_MEM_new();
> BIO_set_mem_buf(in, bm, 0);
>
> if (BIO_write(in, buffer, strlen(buffer)) <= 0)
> {
> perror(buffer);
> goto err;
> }
> if ((cert=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
> {
> BIO_printf(bio_err,"Error reading certificate in %s\n",
> cert);
> goto err;
> }
> ok = 0;
> err:
> if (bm != NULL) BUF_MEM_free(bm);
> if (in != NULL) BIO_free(in);
> if (bm != NULL) BUF_MEM_free(bm);
> if(bio_err != NULL) BIO_free(bio_err);
> return(ok);
> }
> int Init_CryptoLib()
> {
> FILE *fp;
> char buffer[4096];
> int i;
>
> /* Gen_rand();*/
>
> if(( i = system("/usr/bin/ps -ef > /tmp/newrand.out")) < 0){
> printf("Error creating Seed file in /tmp");
> exit(0);
> }
>
> fp = fopen("/tmp/newrand.out", "r");
>
> if (!fp)
> return (USOERR_CA_FILE_ERR);
>
> i = fread(buffer, 1, 1024, fp);
>
> fclose(fp);
>
> RAND_seed(buffer, i);
> PKCS12_lib_init();
>
> return(0);
>
> }
> #ifdef __cplusplus
> }
> #endif
>
--
------------------------------------------------------
Douglas Wikström <[EMAIL PROTECTED]>
------------------------------------------------------
Yes, God created Man before Woman,
but one always makes a draft before the masterpiece.
------------------------------------------------------
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List [EMAIL PROTECTED]
Automated List Manager [EMAIL PROTECTED]