int main(int argc, char const *argv[]) { PKCS7 *p7; FILE *fp = NULL; PKCS7_SIGNER_INFO *si; STACK_OF(PKCS7_SIGNER_INFO) *sk; X509_STORE_CTX cert_ctx; X509_STORE *cert_store; BIO *mybio; int ret, len, i; unsigned char *errordesc; unsigned long errorno; unsigned char data[2028], *p, *buf; OpenSSL_add_all_algorithms(); fp = fopen("p7signed.cer", "rb"); if(fp == NULL) return 0; len = fread(data, 1, 2048, fp); fclose(fp); p = data; p7 = d2i_PKCS7(NULL, (const unsigned char **)&p, len); mybio = PKCS7_dataInit(p7, NULL); sk = PKCS7_get_signer_info(p7); if(sk == NULL) { printf("no signer in p7\n"); return 0; } cert_store=X509_STORE_new(); X509_STORE_set_verify_cb_func(cert_store,verify_callback);//必须要有回调设置 for(i = 0; i < sk_PKCS7_SIGNER_INFO_num(sk); i++) { si = sk_PKCS7_SIGNER_INFO_value(sk, i); ret = PKCS7_dataVerify(cert_store, &cert_ctx, mybio, p7, si); if(ret == 1) printf("succ in pkcs7 signed data verify\n"); else printf("fail in pkcs7 signed data verify\n"); } X509_STORE_free(cert_store); PKCS7_free(p7); return 1; }
/* * call-seq: * X509::Store.new => store * */ static VALUE ossl_x509store_initialize(int argc, VALUE *argv, VALUE self) { X509_STORE *store; /* BUG: This method takes any number of arguments but appears to ignore them. */ GetX509Store(self, store); store->ex_data.sk = NULL; X509_STORE_set_verify_cb_func(store, ossl_verify_cb); ossl_x509store_set_vfy_cb(self, Qnil); #if (OPENSSL_VERSION_NUMBER < 0x00907000L) rb_iv_set(self, "@flags", INT2NUM(0)); rb_iv_set(self, "@purpose", INT2NUM(0)); rb_iv_set(self, "@trust", INT2NUM(0)); #endif /* last verification status */ rb_iv_set(self, "@error", Qnil); rb_iv_set(self, "@error_string", Qnil); rb_iv_set(self, "@chain", Qnil); rb_iv_set(self, "@time", Qnil); return self; }
IoSecureServer *IoSecureServer_setCRLFile(IoSecureServer *self, IoObject *locals, IoMessage *msg) { SSL_CTX *ctx = OCTX(self); IoSeq *pathSeq = IoMessage_locals_seqArgAt_(msg, locals, 0); char *path = IoSeq_asCString(pathSeq); if(ctx == NULL) { IoState_error_(IOSTATE, msg, "SecureServer has no SSL_CTX"); return IONIL(self); } X509_STORE *store = SSL_CTX_get_cert_store(ctx); X509_STORE_set_verify_cb_func(store, IoSecureSockets_Verify_CRL_Callback); X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); X509_LOOKUP *lookup; if (!(lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file ()))) { ERR_print_errors_fp(stderr); IoState_error_(IOSTATE, msg, "Error creating X509_LOOKUP object."); return IONIL(self); } if (X509_load_crl_file(lookup, path, X509_FILETYPE_PEM) != 1) { ERR_print_errors_fp(stderr); IoState_error_(IOSTATE, msg, "Error loading CRL from file %s\n", path); return IONIL(self); } return self; }
static X509_STORE *create_store(nsp_state *N) { #define __FN__ __FILE__ ":create_store()" X509_STORE *store; X509_LOOKUP *lookup; if (!(store = X509_STORE_new())) { n_warn(N, __FN__, "Error creating X509_STORE_CTX object"); goto err; } X509_STORE_set_verify_cb_func(store, verify_callback); if (X509_STORE_load_locations(store, CA_FILE, CA_DIR) != 1) { n_warn(N, __FN__, "Error loading the CA file or directory"); goto err; } if (X509_STORE_set_default_paths(store) != 1) { n_warn(N, __FN__, "Error loading the system-wide CA certificates"); goto err; } if (!(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()))) { n_warn(N, __FN__, "Error creating X509_LOOKUP object"); goto err; } if (X509_load_crl_file(lookup, CRL_FILE, X509_FILETYPE_PEM) != 1) { n_warn(N, __FN__, "Error reading the CRL file"); goto err; } X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); return store; err: return NULL; #undef __FN__ }
int main(int argc, char *argv[]) { X509 *cert; X509_STORE *store; X509_LOOKUP *lookup; X509_STORE_CTX *verify_ctx; FILE *fp; OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); /* frist read the client certificate */ if (!(fp = fopen(CLIENT_CERT, "r"))) { int_error("Error reading client certificate file"); } if (!(cert = PEM_read_X509(fp, NULL, NULL, NULL))) { int_error("Error reading client certificate in file"); } fclose(fp); /* create the cert store and set the verify callback */ if (!(store = X509_STORE_new())) { int_error("Error creating X509_STORE_CTX object"); } X509_STORE_set_verify_cb_func(store, verify_callback); /* load the CA certificates and CRLs */ if (X509_STORE_load_locations(store, CA_FILE, CA_DIR) != 1) { int_error("Error loading the CA file or directory"); } if (X509_STORE_set_default_paths(store) != 1) { int_error("Error loading the system-wide CA certificates"); } if (!(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()))) { int_error("Error creating X509_LOOKUP object"); } if (X509_load_crl_file(lookup, CRL_FILE, X509_FILETYPE_PEM) != 1) { int_error("Error reading the CRL file"); } /* set the flags of the store so that the CRLs are consulted */ X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); /* create a verification context and initialize it */ if (!(verify_ctx = X509_STORE_CTX_new())) { int_error("Error creating X509_STORE_CTX object"); } if (X509_STORE_CTX_init(verify_ctx, store, cert, NULL) != 1) { int_error("Error initializing verification context"); } /* verify the certificate */ if (X509_verify_cert(verify_ctx) != 1) { int_error("Error verifying the certificate"); } else { printf("Certificate verified correctly!\n"); } return 0; }
static X509_STORE *create_cert_store(char *ca_path, char *ca_file) { X509_STORE *cert_ctx = NULL; X509_LOOKUP *lookup = NULL; int i; /* Creating the X509_STORE object. */ cert_ctx = X509_STORE_new(); /* Setting the callback for certificate chain verification. */ X509_STORE_set_verify_cb_func(cert_ctx, verify_cb); /* Adding a trusted certificate directory source. */ if (ca_path) { lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir()); if (lookup == NULL) { BIO_printf(bio_err, "memory allocation failure\n"); goto err; } i = X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM); if (!i) { BIO_printf(bio_err, "Error loading directory %s\n", ca_path); goto err; } } /* Adding a trusted certificate file source. */ if (ca_file) { lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file()); if (lookup == NULL) { BIO_printf(bio_err, "memory allocation failure\n"); goto err; } i = X509_LOOKUP_load_file(lookup, ca_file, X509_FILETYPE_PEM); if (!i) { BIO_printf(bio_err, "Error loading file %s\n", ca_file); goto err; } } return cert_ctx; err: X509_STORE_free(cert_ctx); return NULL; }
/// \brief Used by pkcs7_main() - not to be used directly. /// /// \param N/A /// \return N/A /// X509_STORE * create_store (void) { X509_STORE *store; X509_LOOKUP *lookup; /* create the cert store and set the verify callback */ if (!(store = X509_STORE_new ())) { fprintf (stderr, "Error creating X509_STORE_CTX object\n"); goto err; } X509_STORE_set_verify_cb_func (store, verify_callback); /* load the CA certificates and CRLs */ if (X509_STORE_load_locations (store, CA_FILE, CA_DIR) != 1) { fprintf (stderr, "Error loading the CA file or directory\n"); goto err; } if (X509_STORE_set_default_paths (store) != 1) { fprintf (stderr, "Error loading the system-wide CA certificates\n"); goto err; } if (!(lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file ()))) { fprintf (stderr, "Error creating X509_LOOKUP object\n"); goto err; } /* if (X509_load_crl_file (lookup, CRL_FILE, X509_FILETYPE_PEM) != 1) { fprintf (stderr, "Error reading the CRL file\n"); goto err; } */ /* set the flags of the store so that CRLs are consulted */ X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); return store; err: return NULL; }
/* This function makes sure the certificate is still valid by not having any * compromised certificates in the chain. * If there is no Certificate Revocation List (CRL) it may be that the private * keys have not been compromised or the CRL has not been generated by the * Certificate Authority (CA) * * returns: 0 if certificate is valid, X509 store error code otherwise */ static int validate_certificate(void) { X509_LOOKUP *lookup = NULL; X509_STORE_CTX *verify_ctx = NULL; /* TODO: CRL and Chains are not required for the current setup, but we may * implement them in the future if (!crl) { printf("No certificate revocation list provided\n"); } if (!chain) { printf("No certificate chain provided\n"); } */ /* create the cert store and set the verify callback */ if (!(store = X509_STORE_new())) { fprintf(stderr, "Failed X509_STORE_new() for %s\n", CERTNAME); goto error; } X509_STORE_set_verify_cb_func(store, verify_callback); /* Add the certificates to be verified to the store */ if (!(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()))) { fprintf(stderr, "Failed X509_STORE_add_lookup() for %s\n", CERTNAME); goto error; } /* Load the our Root cert, which can be in either DER or PEM format */ if (!X509_load_cert_file(lookup, CERTNAME, X509_FILETYPE_PEM)) { fprintf(stderr, "Failed X509_load_cert_file() for %s\n", CERTNAME); goto error; } if (crl) { if (!(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())) || (X509_load_crl_file(lookup, crl, X509_FILETYPE_PEM) != 1)) { fprintf(stderr, "Failed X509 crl init for %s\n", CERTNAME); goto error; } /* set the flags of the store so that CLRs are consulted */ X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); } /* create a verification context and initialize it */ if (!(verify_ctx = X509_STORE_CTX_new())) { fprintf(stderr, "Failed X509_STORE_CTX_new() for %s\n", CERTNAME); goto error; } if (X509_STORE_CTX_init(verify_ctx, store, cert, NULL) != 1) { fprintf(stderr, "Failed X509_STORE_CTX_init() for %s\n", CERTNAME); goto error; } /* Specify which cert to validate in the verify context. * This is required because we may add multiple certs to the X509 store, * but we want to validate a specific one out of the group/chain. */ X509_STORE_CTX_set_cert(verify_ctx, cert); /* verify the certificate */ if (X509_verify_cert(verify_ctx) != 1) { fprintf(stderr, "Failed X509_verify_cert() for %s\n", CERTNAME); goto error; } X509_STORE_CTX_free(verify_ctx); /* Certificate verified correctly */ return 0; error: ERR_print_errors_fp(stderr); if (verify_ctx) { X509_STORE_CTX_free(verify_ctx); } return verify_ctx->error; }
/* This function makes sure the certificate is still valid by not having any * compromised certificates in the chain. * If there is no Certificate Revocation List (CRL) it may be that the private * keys have not been compromised or the CRL has not been generated by the * Certificate Authority (CA) * * returns: 0 if certificate is valid, X509 store error code otherwise */ static int validate_certificate(X509 *cert, const char *certificate_path, const char *crl) { X509_LOOKUP *lookup = NULL; X509_STORE_CTX *verify_ctx = NULL; //TODO: Implement a chain verification when required /* create the cert store and set the verify callback */ if (!(store = X509_STORE_new())) { error("Failed X509_STORE_new() for %s\n", certificate_path); goto error; } X509_STORE_set_verify_cb_func(store, verify_callback); if (X509_STORE_set_purpose(store, X509_PURPOSE_ANY) != 1) { error("Failed X509_STORE_set_purpose() for %s\n", certificate_path); goto error; } /* Add the certificates to be verified to the store */ if (!(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()))) { error("Failed X509_STORE_add_lookup() for %s\n", certificate_path); goto error; } /* Load the our Root cert, which can be in either DER or PEM format */ if (!X509_load_cert_file(lookup, certificate_path, X509_FILETYPE_PEM)) { error("Failed X509_load_cert_file() for %s\n", certificate_path); goto error; } if (crl) { if (!(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())) || (X509_load_crl_file(lookup, crl, X509_FILETYPE_PEM) != 1)) { error("Failed X509 crl init for %s\n", certificate_path); goto error; } /* set the flags of the store so that CLRs are consulted */ X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); } /* create a verification context and initialize it */ if (!(verify_ctx = X509_STORE_CTX_new())) { error("Failed X509_STORE_CTX_new() for %s\n", certificate_path); goto error; } if (X509_STORE_CTX_init(verify_ctx, store, cert, NULL) != 1) { error("Failed X509_STORE_CTX_init() for %s\n", certificate_path); goto error; } /* Specify which cert to validate in the verify context. * This is required because we may add multiple certs to the X509 store, * but we want to validate a specific one out of the group/chain. */ X509_STORE_CTX_set_cert(verify_ctx, cert); /* verify the certificate */ if (X509_verify_cert(verify_ctx) != 1) { error("Failed X509_verify_cert() for %s\n", certificate_path); goto error; } X509_STORE_CTX_free(verify_ctx); if (validate_authority(cert) < 0) { error("Failed to validate certificate using 'Authority Information Access'\n"); return -1; } /* Certificate verified correctly */ return 0; error: ERR_print_errors_fp(stderr); if (verify_ctx) { X509_STORE_CTX_free(verify_ctx); } return X509_STORE_CTX_get_error(verify_ctx); }
static int pk7_verify(X509_STORE *cert_store, PKCS7 *p7, BIO *detached, char *ebuf, int ebufsize) { PKCS7_SIGNER_INFO *si; verify_context vctx; BIO *p7bio=NULL; char readbuf[1024*4]; int res = 1; int i; STACK_OF(PKCS7_SIGNER_INFO) *sk; vctx.err = X509_V_OK; ebuf[0] = 0; OpenSSL_add_all_algorithms(); EVP_add_digest(EVP_md5()); EVP_add_digest(EVP_sha1()); ERR_load_crypto_strings(); ERR_clear_error(); X509_VERIFY_PARAM_set_flags(cert_store->param, X509_V_FLAG_CB_ISSUER_CHECK); X509_STORE_set_verify_cb_func(cert_store, verify_callback); p7bio = PKCS7_dataInit(p7, detached); /* We now have to 'read' from p7bio to calculate digests etc. */ while (BIO_read(p7bio, readbuf, sizeof(readbuf)) > 0) ; /* We can now verify signatures */ sk = PKCS7_get_signer_info(p7); if (sk == NULL) { /* there are no signatures on this data */ res = 0; fz_strlcpy(ebuf, "No signatures", ebufsize); goto exit; } for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sk); i++) { int rc; si = sk_PKCS7_SIGNER_INFO_value(sk, i); rc = PKCS7_dataVerify(cert_store, &vctx.x509_ctx, p7bio,p7, si); if (rc <= 0 || vctx.err != X509_V_OK) { char tbuf[120]; if (rc <= 0) { fz_strlcpy(ebuf, ERR_error_string(ERR_get_error(), tbuf), ebufsize); } else { /* Error while checking the certificate chain */ snprintf(ebuf, ebufsize, "%s(%d): %s", X509_verify_cert_error_string(vctx.err), vctx.err, vctx.certdesc); } res = 0; goto exit; } } exit: X509_STORE_CTX_cleanup(&vctx.x509_ctx); ERR_free_strings(); return res; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int operation = 0; int ret = 0; char **args; const char *inmode = "r", *outmode = "w"; char *infile = NULL, *outfile = NULL; char *signerfile = NULL, *recipfile = NULL; char *certfile = NULL, *keyfile = NULL, *contfile=NULL; const EVP_CIPHER *cipher = NULL; PKCS7 *p7 = NULL; X509_STORE *store = NULL; X509 *cert = NULL, *recip = NULL, *signer = NULL; EVP_PKEY *key = NULL; STACK_OF(X509) *encerts = NULL, *other = NULL; BIO *in = NULL, *out = NULL, *indata = NULL; int badarg = 0; int flags = PKCS7_DETACHED; char *to = NULL, *from = NULL, *subject = NULL; char *CAfile = NULL, *CApath = NULL; char *passargin = NULL, *passin = NULL; char *inrand = NULL; int need_rand = 0; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; int keyform = FORMAT_PEM; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif X509_VERIFY_PARAM *vpm = NULL; args = argv + 1; ret = 1; apps_startup(); if (bio_err == NULL) { if ((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT); } if (!load_config(bio_err, NULL)) goto end; while (!badarg && *args && *args[0] == '-') { if (!strcmp (*args, "-encrypt")) operation = SMIME_ENCRYPT; else if (!strcmp (*args, "-decrypt")) operation = SMIME_DECRYPT; else if (!strcmp (*args, "-sign")) operation = SMIME_SIGN; else if (!strcmp (*args, "-verify")) operation = SMIME_VERIFY; else if (!strcmp (*args, "-pk7out")) operation = SMIME_PK7OUT; #ifndef OPENSSL_NO_DES else if (!strcmp (*args, "-des3")) cipher = EVP_des_ede3_cbc(); else if (!strcmp (*args, "-des")) cipher = EVP_des_cbc(); #endif #ifndef OPENSSL_NO_SEED else if (!strcmp (*args, "-seed")) cipher = EVP_seed_cbc(); #endif #ifndef OPENSSL_NO_RC2 else if (!strcmp (*args, "-rc2-40")) cipher = EVP_rc2_40_cbc(); else if (!strcmp (*args, "-rc2-128")) cipher = EVP_rc2_cbc(); else if (!strcmp (*args, "-rc2-64")) cipher = EVP_rc2_64_cbc(); #endif #ifndef OPENSSL_NO_AES else if (!strcmp(*args,"-aes128")) cipher = EVP_aes_128_cbc(); else if (!strcmp(*args,"-aes192")) cipher = EVP_aes_192_cbc(); else if (!strcmp(*args,"-aes256")) cipher = EVP_aes_256_cbc(); #endif #ifndef OPENSSL_NO_CAMELLIA else if (!strcmp(*args,"-camellia128")) cipher = EVP_camellia_128_cbc(); else if (!strcmp(*args,"-camellia192")) cipher = EVP_camellia_192_cbc(); else if (!strcmp(*args,"-camellia256")) cipher = EVP_camellia_256_cbc(); #endif else if (!strcmp (*args, "-text")) flags |= PKCS7_TEXT; else if (!strcmp (*args, "-nointern")) flags |= PKCS7_NOINTERN; else if (!strcmp (*args, "-noverify")) flags |= PKCS7_NOVERIFY; else if (!strcmp (*args, "-nochain")) flags |= PKCS7_NOCHAIN; else if (!strcmp (*args, "-nocerts")) flags |= PKCS7_NOCERTS; else if (!strcmp (*args, "-noattr")) flags |= PKCS7_NOATTR; else if (!strcmp (*args, "-nodetach")) flags &= ~PKCS7_DETACHED; else if (!strcmp (*args, "-nosmimecap")) flags |= PKCS7_NOSMIMECAP; else if (!strcmp (*args, "-binary")) flags |= PKCS7_BINARY; else if (!strcmp (*args, "-nosigs")) flags |= PKCS7_NOSIGS; else if (!strcmp (*args, "-nooldmime")) flags |= PKCS7_NOOLDMIMETYPE; else if (!strcmp (*args, "-crlfeol")) flags |= PKCS7_CRLFEOL; else if (!strcmp(*args,"-rand")) { if (args[1]) { args++; inrand = *args; } else badarg = 1; need_rand = 1; } #ifndef OPENSSL_NO_ENGINE else if (!strcmp(*args,"-engine")) { if (args[1]) { args++; engine = *args; } else badarg = 1; } #endif else if (!strcmp(*args,"-passin")) { if (args[1]) { args++; passargin = *args; } else badarg = 1; } else if (!strcmp (*args, "-to")) { if (args[1]) { args++; to = *args; } else badarg = 1; } else if (!strcmp (*args, "-from")) { if (args[1]) { args++; from = *args; } else badarg = 1; } else if (!strcmp (*args, "-subject")) { if (args[1]) { args++; subject = *args; } else badarg = 1; } else if (!strcmp (*args, "-signer")) { if (args[1]) { args++; signerfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-recip")) { if (args[1]) { args++; recipfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-inkey")) { if (args[1]) { args++; keyfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-keyform")) { if (args[1]) { args++; keyform = str2fmt(*args); } else badarg = 1; } else if (!strcmp (*args, "-certfile")) { if (args[1]) { args++; certfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-CAfile")) { if (args[1]) { args++; CAfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-CApath")) { if (args[1]) { args++; CApath = *args; } else badarg = 1; } else if (!strcmp (*args, "-in")) { if (args[1]) { args++; infile = *args; } else badarg = 1; } else if (!strcmp (*args, "-inform")) { if (args[1]) { args++; informat = str2fmt(*args); } else badarg = 1; } else if (!strcmp (*args, "-outform")) { if (args[1]) { args++; outformat = str2fmt(*args); } else badarg = 1; } else if (!strcmp (*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-content")) { if (args[1]) { args++; contfile = *args; } else badarg = 1; } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) continue; else badarg = 1; args++; } if (operation == SMIME_SIGN) { if (!signerfile) { BIO_printf(bio_err, "No signer certificate specified\n"); badarg = 1; } need_rand = 1; } else if (operation == SMIME_DECRYPT) { if (!recipfile && !keyfile) { BIO_printf(bio_err, "No recipient certificate or key specified\n"); badarg = 1; } } else if (operation == SMIME_ENCRYPT) { if (!*args) { BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); badarg = 1; } need_rand = 1; } else if (!operation) badarg = 1; if (badarg) { BIO_printf (bio_err, "Usage smime [options] cert.pem ...\n"); BIO_printf (bio_err, "where options are\n"); BIO_printf (bio_err, "-encrypt encrypt message\n"); BIO_printf (bio_err, "-decrypt decrypt encrypted message\n"); BIO_printf (bio_err, "-sign sign message\n"); BIO_printf (bio_err, "-verify verify signed message\n"); BIO_printf (bio_err, "-pk7out output PKCS#7 structure\n"); #ifndef OPENSSL_NO_DES BIO_printf (bio_err, "-des3 encrypt with triple DES\n"); BIO_printf (bio_err, "-des encrypt with DES\n"); #endif #ifndef OPENSSL_NO_SEED BIO_printf (bio_err, "-seed encrypt with SEED\n"); #endif #ifndef OPENSSL_NO_RC2 BIO_printf (bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); BIO_printf (bio_err, "-rc2-64 encrypt with RC2-64\n"); BIO_printf (bio_err, "-rc2-128 encrypt with RC2-128\n"); #endif #ifndef OPENSSL_NO_AES BIO_printf (bio_err, "-aes128, -aes192, -aes256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc aes\n"); #endif #ifndef OPENSSL_NO_CAMELLIA BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc camellia\n"); #endif BIO_printf (bio_err, "-nointern don't search certificates in message for signer\n"); BIO_printf (bio_err, "-nosigs don't verify message signature\n"); BIO_printf (bio_err, "-noverify don't verify signers certificate\n"); BIO_printf (bio_err, "-nocerts don't include signers certificate when signing\n"); BIO_printf (bio_err, "-nodetach use opaque signing\n"); BIO_printf (bio_err, "-noattr don't include any signed attributes\n"); BIO_printf (bio_err, "-binary don't translate message to text\n"); BIO_printf (bio_err, "-certfile file other certificates file\n"); BIO_printf (bio_err, "-signer file signer certificate file\n"); BIO_printf (bio_err, "-recip file recipient certificate file for decryption\n"); BIO_printf (bio_err, "-in file input file\n"); BIO_printf (bio_err, "-inform arg input format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-inkey file input private key (if not signer or recipient)\n"); BIO_printf (bio_err, "-keyform arg input private key format (PEM or ENGINE)\n"); BIO_printf (bio_err, "-out file output file\n"); BIO_printf (bio_err, "-outform arg output format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-content file supply or override content for detached signature\n"); BIO_printf (bio_err, "-to addr to address\n"); BIO_printf (bio_err, "-from ad from address\n"); BIO_printf (bio_err, "-subject s subject\n"); BIO_printf (bio_err, "-text include or delete text MIME headers\n"); BIO_printf (bio_err, "-CApath dir trusted certificates directory\n"); BIO_printf (bio_err, "-CAfile file trusted certificates file\n"); BIO_printf (bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n"); BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n"); #endif BIO_printf (bio_err, "-passin arg input file pass phrase source\n"); BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); BIO_printf (bio_err, "cert.pem recipient certificate(s) for encryption\n"); goto end; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (need_rand) { app_RAND_load_file(NULL, bio_err, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); } ret = 2; if (operation != SMIME_SIGN) flags &= ~PKCS7_DETACHED; if (operation & SMIME_OP) { if (flags & PKCS7_BINARY) inmode = "rb"; if (outformat == FORMAT_ASN1) outmode = "wb"; } else { if (flags & PKCS7_BINARY) outmode = "wb"; if (informat == FORMAT_ASN1) inmode = "rb"; } if (operation == SMIME_ENCRYPT) { if (!cipher) { #ifndef OPENSSL_NO_RC2 cipher = EVP_rc2_40_cbc(); #else BIO_printf(bio_err, "No cipher selected\n"); goto end; #endif } encerts = sk_X509_new_null(); while (*args) { if (!(cert = load_cert(bio_err,*args,FORMAT_PEM, NULL, e, "recipient certificate file"))) { #if 0 /* An appropriate message is already printed */ BIO_printf(bio_err, "Can't read recipient certificate file %s\n", *args); #endif goto end; } sk_X509_push(encerts, cert); cert = NULL; args++; } } if (signerfile && (operation == SMIME_SIGN)) { if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM, NULL, e, "signer certificate"))) { #if 0 /* An appropri message has already been printed */ BIO_printf(bio_err, "Can't read signer certificate file %s\n", signerfile); #endif goto end; } } if (certfile) { if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL, e, "certificate file"))) { #if 0 /* An appropriate message has already been printed */ BIO_printf(bio_err, "Can't read certificate file %s\n", certfile); #endif ERR_print_errors(bio_err); goto end; } } if (recipfile && (operation == SMIME_DECRYPT)) { if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL, e, "recipient certificate file"))) { #if 0 /* An appropriate message has alrady been printed */ BIO_printf(bio_err, "Can't read recipient certificate file %s\n", recipfile); #endif ERR_print_errors(bio_err); goto end; } } if (operation == SMIME_DECRYPT) { if (!keyfile) keyfile = recipfile; } else if (operation == SMIME_SIGN) { if (!keyfile) keyfile = signerfile; } else keyfile = NULL; if (keyfile) { key = load_key(bio_err, keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; } if (infile) { if (!(in = BIO_new_file(infile, inmode))) { BIO_printf (bio_err, "Can't open input file %s\n", infile); goto end; } } else in = BIO_new_fp(stdin, BIO_NOCLOSE); if (outfile) { if (!(out = BIO_new_file(outfile, outmode))) { BIO_printf (bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } if (operation == SMIME_VERIFY) { if (!(store = setup_verify(bio_err, CAfile, CApath))) goto end; X509_STORE_set_verify_cb_func(store, smime_cb); if (vpm) X509_STORE_set1_param(store, vpm); } ret = 3; if (operation == SMIME_ENCRYPT) p7 = PKCS7_encrypt(encerts, in, cipher, flags); else if (operation == SMIME_SIGN) { /* If detached data and SMIME output enable partial * signing. */ if ((flags & PKCS7_DETACHED) && (outformat == FORMAT_SMIME)) flags |= PKCS7_STREAM; p7 = PKCS7_sign(signer, key, other, in, flags); } else { if (informat == FORMAT_SMIME) p7 = SMIME_read_PKCS7(in, &indata); else if (informat == FORMAT_PEM) p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); else if (informat == FORMAT_ASN1) p7 = d2i_PKCS7_bio(in, NULL); else { BIO_printf(bio_err, "Bad input format for PKCS#7 file\n"); goto end; } if (!p7) { BIO_printf(bio_err, "Error reading S/MIME message\n"); goto end; } if (contfile) { BIO_free(indata); if (!(indata = BIO_new_file(contfile, "rb"))) { BIO_printf(bio_err, "Can't read content file %s\n", contfile); goto end; } } } if (!p7) { BIO_printf(bio_err, "Error creating PKCS#7 structure\n"); goto end; } ret = 4; if (operation == SMIME_DECRYPT) { if (!PKCS7_decrypt(p7, key, recip, out, flags)) { BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n"); goto end; } } else if (operation == SMIME_VERIFY) { STACK_OF(X509) *signers; if (PKCS7_verify(p7, other, store, indata, out, flags)) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); goto end; } signers = PKCS7_get0_signers(p7, other, flags); if (!save_certs(signerfile, signers)) { BIO_printf(bio_err, "Error writing signers to %s\n", signerfile); ret = 5; goto end; } sk_X509_free(signers); } else if (operation == SMIME_PK7OUT) PEM_write_bio_PKCS7(out, p7); else { if (to) BIO_printf(out, "To: %s\n", to); if (from) BIO_printf(out, "From: %s\n", from); if (subject) BIO_printf(out, "Subject: %s\n", subject); if (outformat == FORMAT_SMIME) SMIME_write_PKCS7(out, p7, in, flags); else if (outformat == FORMAT_PEM) PEM_write_bio_PKCS7(out,p7); else if (outformat == FORMAT_ASN1) i2d_PKCS7_bio(out,p7); else { BIO_printf(bio_err, "Bad output format for PKCS#7 file\n"); goto end; } } ret = 0; end: if (need_rand) app_RAND_write_file(NULL, bio_err); if (ret) ERR_print_errors(bio_err); sk_X509_pop_free(encerts, X509_free); sk_X509_pop_free(other, X509_free); if (vpm) X509_VERIFY_PARAM_free(vpm); X509_STORE_free(store); X509_free(cert); X509_free(recip); X509_free(signer); EVP_PKEY_free(key); PKCS7_free(p7); BIO_free(in); BIO_free(indata); BIO_free_all(out); if (passin) OPENSSL_free(passin); return (ret); }
/*============================================================================ * OpcUa_P_OpenSSL_CertificateStore_Open *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_PKI_OpenCertificateStore( OpcUa_PKIProvider* a_pProvider, OpcUa_Void** a_ppCertificateStore) /* type depends on store implementation */ { OpcUa_P_OpenSSL_CertificateStore_Config* pCertificateStoreCfg; X509_STORE* pStore; X509_LOOKUP* pLookup; char CertFile[MAX_PATH]; struct dirent **dirlist = NULL; int numCertificates = 0, i; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "PKI_OpenCertificateStore"); OpcUa_ReturnErrorIfArgumentNull(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pProvider->Handle); OpcUa_ReturnErrorIfArgumentNull(a_ppCertificateStore); *a_ppCertificateStore = OpcUa_Null; pCertificateStoreCfg = (OpcUa_P_OpenSSL_CertificateStore_Config*)a_pProvider->Handle; if(!(*a_ppCertificateStore = pStore = X509_STORE_new())) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } X509_STORE_set_verify_cb_func(pStore, OpcUa_P_OpenSSL_CertificateStore_Verify_Callback); if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_USE_DEFAULT_CERT_CRL_LOOKUP_METHOD) { if(X509_STORE_set_default_paths(pStore) != 1) { OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_STORE_set_default_paths!\n"); OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } if(!(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_DONT_ADD_TRUST_LIST_TO_ROOT_CERTIFICATES)) { if(pCertificateStoreCfg->CertificateTrustListLocation == OpcUa_Null || pCertificateStoreCfg->CertificateTrustListLocation[0] == '\0') { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } /* how to search for certificate & CRLs */ if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file()))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } /* how to search for certificate & CRLs */ numCertificates = scandir(pCertificateStoreCfg->CertificateTrustListLocation, &dirlist, certificate_filter_der, alphasort); for (i=0; i<numCertificates; i++) { uStatus = OpcUa_P_OpenSSL_BuildFullPath(pCertificateStoreCfg->CertificateTrustListLocation, dirlist[i]->d_name, MAX_PATH, CertFile); OpcUa_GotoErrorIfBad(uStatus); /* add CACertificate lookup */ if(X509_LOOKUP_load_file(pLookup, CertFile, X509_FILETYPE_ASN1) != 1) /*DER encoded*/ { OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_LOOKUP_load_file: skipping %s\n", CertFile); } } for (i=0; i<numCertificates; i++) { free(dirlist[i]); } free(dirlist); dirlist = NULL; } if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_ADD_UNTRUSTED_LIST_TO_ROOT_CERTIFICATES) { if(pCertificateStoreCfg->CertificateUntrustedListLocation == OpcUa_Null || pCertificateStoreCfg->CertificateUntrustedListLocation[0] == '\0') { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_UNTRUSTED_LIST_IS_INDEX) { /* how to search for certificate */ if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_hash_dir()))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } /* add hash lookup */ if(X509_LOOKUP_add_dir(pLookup, pCertificateStoreCfg->CertificateUntrustedListLocation, X509_FILETYPE_ASN1) != 1) /*DER encoded*/ { OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_LOOKUP_add_dir!\n"); OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } else { /* how to search for certificate & CRLs */ if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file()))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } numCertificates = scandir(pCertificateStoreCfg->CertificateUntrustedListLocation, &dirlist, certificate_filter_der, alphasort); for (i=0; i<numCertificates; i++) { uStatus = OpcUa_P_OpenSSL_BuildFullPath(pCertificateStoreCfg->CertificateUntrustedListLocation, dirlist[i]->d_name, MAX_PATH, CertFile); OpcUa_GotoErrorIfBad(uStatus); /* add CACertificate lookup */ if(X509_LOOKUP_load_file(pLookup, CertFile, X509_FILETYPE_ASN1) != 1) /*DER encoded*/ { OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_LOOKUP_load_file: skipping %s\n", CertFile); } } for (i=0; i<numCertificates; i++) { free(dirlist[i]); } free(dirlist); dirlist = NULL; } } if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL) { if(pCertificateStoreCfg->CertificateRevocationListLocation == OpcUa_Null || pCertificateStoreCfg->CertificateRevocationListLocation[0] == '\0') { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_REVOCATION_LIST_IS_INDEX) { /* how to search for certificate & CRLs */ if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_hash_dir()))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } /* add CRL lookup */ if(X509_LOOKUP_add_dir(pLookup, pCertificateStoreCfg->CertificateRevocationListLocation, X509_FILETYPE_PEM) != 1) /*PEM encoded*/ { OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_LOOKUP_add_dir!\n"); OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } else if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_REVOCATION_LIST_IS_CONCATENATED_PEM_FILE) { /* how to search for certificate & CRLs */ if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file()))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } /* add CRL lookup */ if(X509_load_crl_file(pLookup, pCertificateStoreCfg->CertificateRevocationListLocation, X509_FILETYPE_PEM) != 1) /*PEM encoded*/ { OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_load_crl_file!\n"); } } else { /* how to search for certificate & CRLs */ if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file()))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } numCertificates = scandir(pCertificateStoreCfg->CertificateRevocationListLocation, &dirlist, certificate_filter_crl, alphasort); for (i=0; i<numCertificates; i++) { uStatus = OpcUa_P_OpenSSL_BuildFullPath(pCertificateStoreCfg->CertificateRevocationListLocation, dirlist[i]->d_name, MAX_PATH, CertFile); OpcUa_GotoErrorIfBad(uStatus); if(X509_load_crl_file(pLookup, CertFile, X509_FILETYPE_PEM) != 1) /*PEM encoded*/ { OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_load_crl_file: skipping %s\n", CertFile); } } for (i=0; i<numCertificates; i++) { free(dirlist[i]); } free(dirlist); dirlist = NULL; } if((pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL) == OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL) { /* set the flags of the store so that CRLs are consulted */ if(X509_STORE_set_flags(pStore, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL) != 1) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } else if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ONLY_LEAF) { /* set the flags of the store so that CRLs are consulted */ if(X509_STORE_set_flags(pStore, X509_V_FLAG_CRL_CHECK) != 1) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } } if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_SELF_SIGNED_SIGNATURE) { /* set the flags of the store so that CRLs are consulted */ if(X509_STORE_set_flags(pStore, X509_V_FLAG_CHECK_SS_SIGNATURE) != 1) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_ALLOW_PROXY_CERTIFICATES) { /* set the flags of the store so that CRLs are consulted */ if(X509_STORE_set_flags(pStore, X509_V_FLAG_ALLOW_PROXY_CERTS) != 1) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(dirlist != NULL) { for (i=0; i<numCertificates; i++) { free(dirlist[i]); } free(dirlist); } if(*a_ppCertificateStore != OpcUa_Null) { X509_STORE_free((X509_STORE*)*a_ppCertificateStore); *a_ppCertificateStore = OpcUa_Null; } OpcUa_FinishErrorHandling; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int i,ret=1, badarg = 0; int purpose = -1; char *CApath=NULL,*CAfile=NULL; char *untfile = NULL, *trustfile = NULL; STACK_OF(X509) *untrusted = NULL, *trusted = NULL; X509_STORE *cert_ctx=NULL; X509_LOOKUP *lookup=NULL; X509_VERIFY_PARAM *vpm = NULL; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif cert_ctx=X509_STORE_new(); if (cert_ctx == NULL) goto end; X509_STORE_set_verify_cb_func(cert_ctx,cb); ERR_load_crypto_strings(); apps_startup(); if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto end; argc--; argv++; for (;;) { if (argc >= 1) { if (strcmp(*argv,"-CApath") == 0) { if (argc-- < 1) goto end; CApath= *(++argv); } else if (strcmp(*argv,"-CAfile") == 0) { if (argc-- < 1) goto end; CAfile= *(++argv); } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) { if (badarg) goto end; continue; } else if (strcmp(*argv,"-untrusted") == 0) { if (argc-- < 1) goto end; untfile= *(++argv); } else if (strcmp(*argv,"-trusted") == 0) { if (argc-- < 1) goto end; trustfile= *(++argv); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto end; engine= *(++argv); } #endif else if (strcmp(*argv,"-help") == 0) goto end; else if (strcmp(*argv,"-verbose") == 0) v_verbose=1; else if (argv[0][0] == '-') goto end; else break; argc--; argv++; } else break; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (vpm) X509_STORE_set1_param(cert_ctx, vpm); lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_file()); if (lookup == NULL) abort(); if (CAfile) { i=X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM); if(!i) { BIO_printf(bio_err, "Error loading file %s\n", CAfile); ERR_print_errors(bio_err); goto end; } } else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT); lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_hash_dir()); if (lookup == NULL) abort(); if (CApath) { i=X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM); if(!i) { BIO_printf(bio_err, "Error loading directory %s\n", CApath); ERR_print_errors(bio_err); goto end; } } else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT); ERR_clear_error(); if(untfile) { if(!(untrusted = load_untrusted(untfile))) { BIO_printf(bio_err, "Error loading untrusted file %s\n", untfile); ERR_print_errors(bio_err); goto end; } } if(trustfile) { if(!(trusted = load_untrusted(trustfile))) { BIO_printf(bio_err, "Error loading untrusted file %s\n", trustfile); ERR_print_errors(bio_err); goto end; } } if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, purpose, e); else for (i=0; i<argc; i++) check(cert_ctx,argv[i], untrusted, trusted, purpose, e); ret=0; end: if (ret == 1) { BIO_printf(bio_err,"usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err," [-engine e]"); #endif BIO_printf(bio_err," cert1 cert2 ...\n"); BIO_printf(bio_err,"recognized usages:\n"); for(i = 0; i < X509_PURPOSE_get_count(); i++) { X509_PURPOSE *ptmp; ptmp = X509_PURPOSE_get0(i); BIO_printf(bio_err, "\t%-10s\t%s\n", X509_PURPOSE_get0_sname(ptmp), X509_PURPOSE_get0_name(ptmp)); } } if (vpm) X509_VERIFY_PARAM_free(vpm); if (cert_ctx != NULL) X509_STORE_free(cert_ctx); sk_X509_pop_free(untrusted, X509_free); sk_X509_pop_free(trusted, X509_free); apps_shutdown(); OPENSSL_EXIT(ret); }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int ret=1; X509_REQ *req=NULL; X509 *x=NULL,*xca=NULL; ASN1_OBJECT *objtmp; EVP_PKEY *Upkey=NULL,*CApkey=NULL; ASN1_INTEGER *sno = NULL; int i,num,badops=0; BIO *out=NULL; BIO *STDout=NULL; STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; int informat,outformat,keyformat,CAformat,CAkeyformat; char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL; char *CAkeyfile=NULL,*CAserial=NULL; char *alias=NULL; int text=0,serial=0,hash=0,subject=0,issuer=0,startdate=0,enddate=0; int ocspid=0; int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0; int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0; int C=0; int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0; int pprint = 0; char **pp; X509_STORE *ctx=NULL; X509_REQ *rq=NULL; int fingerprint=0; char buf[256]; const EVP_MD *md_alg,*digest=EVP_md5(); CONF *extconf = NULL; char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL; int need_rand = 0; int checkend=0,checkoffset=0; unsigned long nmflag = 0, certflag = 0; char *engine=NULL; reqfile=0; apps_startup(); if (bio_err == NULL) bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; STDout=BIO_new_fp(stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); STDout = BIO_push(tmpbio, STDout); } #endif informat=FORMAT_PEM; outformat=FORMAT_PEM; keyformat=FORMAT_PEM; CAformat=FORMAT_PEM; CAkeyformat=FORMAT_PEM; ctx=X509_STORE_new(); if (ctx == NULL) goto end; X509_STORE_set_verify_cb_func(ctx,callb); argc--; argv++; num=0; while (argc >= 1) { if (strcmp(*argv,"-inform") == 0) { if (--argc < 1) goto bad; informat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-outform") == 0) { if (--argc < 1) goto bad; outformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-keyform") == 0) { if (--argc < 1) goto bad; keyformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-req") == 0) { reqfile=1; need_rand = 1; } else if (strcmp(*argv,"-CAform") == 0) { if (--argc < 1) goto bad; CAformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-CAkeyform") == 0) { if (--argc < 1) goto bad; CAkeyformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-days") == 0) { if (--argc < 1) goto bad; days=atoi(*(++argv)); if (days == 0) { BIO_printf(STDout,"bad number of days\n"); goto bad; } } else if (strcmp(*argv,"-passin") == 0) { if (--argc < 1) goto bad; passargin= *(++argv); } else if (strcmp(*argv,"-extfile") == 0) { if (--argc < 1) goto bad; extfile= *(++argv); } else if (strcmp(*argv,"-extensions") == 0) { if (--argc < 1) goto bad; extsect= *(++argv); } else if (strcmp(*argv,"-in") == 0) { if (--argc < 1) goto bad; infile= *(++argv); } else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) goto bad; outfile= *(++argv); } else if (strcmp(*argv,"-signkey") == 0) { if (--argc < 1) goto bad; keyfile= *(++argv); sign_flag= ++num; need_rand = 1; } else if (strcmp(*argv,"-CA") == 0) { if (--argc < 1) goto bad; CAfile= *(++argv); CA_flag= ++num; need_rand = 1; } else if (strcmp(*argv,"-CAkey") == 0) { if (--argc < 1) goto bad; CAkeyfile= *(++argv); } else if (strcmp(*argv,"-CAserial") == 0) { if (--argc < 1) goto bad; CAserial= *(++argv); } else if (strcmp(*argv,"-set_serial") == 0) { if (--argc < 1) goto bad; if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv)))) goto bad; } else if (strcmp(*argv,"-addtrust") == 0) { if (--argc < 1) goto bad; if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) { BIO_printf(bio_err, "Invalid trust object value %s\n", *argv); goto bad; } if (!trust) trust = sk_ASN1_OBJECT_new_null(); sk_ASN1_OBJECT_push(trust, objtmp); trustout = 1; } else if (strcmp(*argv,"-addreject") == 0) { if (--argc < 1) goto bad; if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) { BIO_printf(bio_err, "Invalid reject object value %s\n", *argv); goto bad; } if (!reject) reject = sk_ASN1_OBJECT_new_null(); sk_ASN1_OBJECT_push(reject, objtmp); trustout = 1; } else if (strcmp(*argv,"-setalias") == 0) { if (--argc < 1) goto bad; alias= *(++argv); trustout = 1; } else if (strcmp(*argv,"-certopt") == 0) { if (--argc < 1) goto bad; if (!set_cert_ex(&certflag, *(++argv))) goto bad; } else if (strcmp(*argv,"-nameopt") == 0) { if (--argc < 1) goto bad; if (!set_name_ex(&nmflag, *(++argv))) goto bad; } else if (strcmp(*argv,"-setalias") == 0) { if (--argc < 1) goto bad; alias= *(++argv); trustout = 1; } else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine= *(++argv); } else if (strcmp(*argv,"-C") == 0) C= ++num; else if (strcmp(*argv,"-email") == 0) email= ++num; else if (strcmp(*argv,"-serial") == 0) serial= ++num; else if (strcmp(*argv,"-modulus") == 0) modulus= ++num; else if (strcmp(*argv,"-pubkey") == 0) pubkey= ++num; else if (strcmp(*argv,"-x509toreq") == 0) x509req= ++num; else if (strcmp(*argv,"-text") == 0) text= ++num; else if (strcmp(*argv,"-hash") == 0) hash= ++num; else if (strcmp(*argv,"-subject") == 0) subject= ++num; else if (strcmp(*argv,"-issuer") == 0) issuer= ++num; else if (strcmp(*argv,"-fingerprint") == 0) fingerprint= ++num; else if (strcmp(*argv,"-dates") == 0) { startdate= ++num; enddate= ++num; } else if (strcmp(*argv,"-purpose") == 0) pprint= ++num; else if (strcmp(*argv,"-startdate") == 0) startdate= ++num; else if (strcmp(*argv,"-enddate") == 0) enddate= ++num; else if (strcmp(*argv,"-checkend") == 0) { if (--argc < 1) goto bad; checkoffset=atoi(*(++argv)); checkend=1; } else if (strcmp(*argv,"-noout") == 0) noout= ++num; else if (strcmp(*argv,"-trustout") == 0) trustout= 1; else if (strcmp(*argv,"-clrtrust") == 0) clrtrust= ++num; else if (strcmp(*argv,"-clrreject") == 0) clrreject= ++num; else if (strcmp(*argv,"-alias") == 0) aliasout= ++num; else if (strcmp(*argv,"-CAcreateserial") == 0) CA_createserial= ++num; else if (strcmp(*argv,"-clrext") == 0) clrext = 1; #if 1 /* stay backwards-compatible with 0.9.5; this should go away soon */ else if (strcmp(*argv,"-crlext") == 0) { BIO_printf(bio_err,"use -clrext instead of -crlext\n"); clrext = 1; } #endif else if (strcmp(*argv,"-ocspid") == 0) ocspid= ++num; else if ((md_alg=EVP_get_digestbyname(*argv + 1))) { /* ok */ digest=md_alg; } else { BIO_printf(bio_err,"unknown option %s\n",*argv); badops=1; break; } argc--; argv++; } if (badops) { bad: for (pp=x509_usage; (*pp != NULL); pp++) BIO_printf(bio_err,"%s",*pp); goto end; } e = setup_engine(bio_err, engine, 0); if (need_rand) app_RAND_load_file(NULL, bio_err, 0); ERR_load_crypto_strings(); if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (!X509_STORE_set_default_paths(ctx)) { ERR_print_errors(bio_err); goto end; } if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) { CAkeyfile=CAfile; } else if ((CA_flag) && (CAkeyfile == NULL)) { BIO_printf(bio_err,"need to specify a CAkey if using the CA command\n"); goto end; } if (extfile) { long errorline = -1; X509V3_CTX ctx2; extconf = NCONF_new(NULL); if (!NCONF_load(extconf, extfile,&errorline)) { if (errorline <= 0) BIO_printf(bio_err, "error loading the config file '%s'\n", extfile); else BIO_printf(bio_err, "error on line %ld of config file '%s'\n" ,errorline,extfile); goto end; } if (!extsect) { extsect = NCONF_get_string(extconf, "default", "extensions"); if (!extsect) { ERR_clear_error(); extsect = "default"; } } X509V3_set_ctx_test(&ctx2); X509V3_set_nconf(&ctx2, extconf); if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) { BIO_printf(bio_err, "Error Loading extension section %s\n", extsect); ERR_print_errors(bio_err); goto end; } } if (reqfile) { EVP_PKEY *pkey; X509_CINF *ci; BIO *in; if (!sign_flag && !CA_flag) { BIO_printf(bio_err,"We need a private key to sign with\n"); goto end; } in=BIO_new(BIO_s_file()); if (in == NULL) { ERR_print_errors(bio_err); goto end; } if (infile == NULL) BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT); else { if (BIO_read_filename(in,infile) <= 0) { perror(infile); BIO_free(in); goto end; } } req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL); BIO_free(in); if (req == NULL) { ERR_print_errors(bio_err); goto end; } if ( (req->req_info == NULL) || (req->req_info->pubkey == NULL) || (req->req_info->pubkey->public_key == NULL) || (req->req_info->pubkey->public_key->data == NULL)) { BIO_printf(bio_err,"The certificate request appears to corrupted\n"); BIO_printf(bio_err,"It does not contain a public key\n"); goto end; } if ((pkey=X509_REQ_get_pubkey(req)) == NULL) { BIO_printf(bio_err,"error unpacking public key\n"); goto end; } i=X509_REQ_verify(req,pkey); EVP_PKEY_free(pkey); if (i < 0) { BIO_printf(bio_err,"Signature verification error\n"); ERR_print_errors(bio_err); goto end; } if (i == 0) { BIO_printf(bio_err,"Signature did not match the certificate request\n"); goto end; } else BIO_printf(bio_err,"Signature ok\n"); print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag); if ((x=X509_new()) == NULL) goto end; ci=x->cert_info; if (sno) { if (!X509_set_serialNumber(x, sno)) goto end; } else if (!ASN1_INTEGER_set(X509_get_serialNumber(x),0)) goto end; if (!X509_set_issuer_name(x,req->req_info->subject)) goto end; if (!X509_set_subject_name(x,req->req_info->subject)) goto end; X509_gmtime_adj(X509_get_notBefore(x),0); X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days); pkey = X509_REQ_get_pubkey(req); X509_set_pubkey(x,pkey); EVP_PKEY_free(pkey); } else x=load_cert(bio_err,infile,informat,NULL,e,"Certificate"); if (x == NULL) goto end; if (CA_flag) { xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate"); if (xca == NULL) goto end; } if (!noout || text) { OBJ_create("2.99999.3", "SET.ex3","SET x509v3 extension 3"); out=BIO_new(BIO_s_file()); if (out == NULL) { ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out,stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out,outfile) <= 0) { perror(outfile); goto end; } } } if (alias) X509_alias_set1(x, (unsigned char *)alias, -1); if (clrtrust) X509_trust_clear(x); if (clrreject) X509_reject_clear(x); if (trust) { for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) { objtmp = sk_ASN1_OBJECT_value(trust, i); X509_add1_trust_object(x, objtmp); } } if (reject) { for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) { objtmp = sk_ASN1_OBJECT_value(reject, i); X509_add1_reject_object(x, objtmp); } } if (num) { for (i=1; i<=num; i++) { if (issuer == i) { print_name(STDout, "issuer= ", X509_get_issuer_name(x), nmflag); } else if (subject == i) { print_name(STDout, "subject= ", X509_get_subject_name(x), nmflag); } else if (serial == i) { BIO_printf(STDout,"serial="); i2a_ASN1_INTEGER(STDout,x->cert_info->serialNumber); BIO_printf(STDout,"\n"); } else if (email == i) { int j; STACK *emlst; emlst = X509_get1_email(x); for (j = 0; j < sk_num(emlst); j++) BIO_printf(STDout, "%s\n", sk_value(emlst, j)); X509_email_free(emlst); } else if (aliasout == i) { unsigned char *alstr; alstr = X509_alias_get0(x, NULL); if (alstr) BIO_printf(STDout,"%s\n", alstr); else BIO_puts(STDout,"<No Alias>\n"); } else if (hash == i) { BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x)); } else if (pprint == i) { X509_PURPOSE *ptmp; int j; BIO_printf(STDout, "Certificate purposes:\n"); for (j = 0; j < X509_PURPOSE_get_count(); j++) { ptmp = X509_PURPOSE_get0(j); purpose_print(STDout, x, ptmp); } } else if (modulus == i) { EVP_PKEY *pkey; pkey=X509_get_pubkey(x); if (pkey == NULL) { BIO_printf(bio_err,"Modulus=unavailable\n"); ERR_print_errors(bio_err); goto end; } BIO_printf(STDout,"Modulus="); #ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA) BN_print(STDout,pkey->pkey.rsa->n); else #endif #ifndef OPENSSL_NO_DSA if (pkey->type == EVP_PKEY_DSA) BN_print(STDout,pkey->pkey.dsa->pub_key); else #endif BIO_printf(STDout,"Wrong Algorithm type"); BIO_printf(STDout,"\n"); EVP_PKEY_free(pkey); } else if (pubkey == i) { EVP_PKEY *pkey; pkey=X509_get_pubkey(x); if (pkey == NULL) { BIO_printf(bio_err,"Error getting public key\n"); ERR_print_errors(bio_err); goto end; } PEM_write_bio_PUBKEY(STDout, pkey); EVP_PKEY_free(pkey); } else if (C == i) { unsigned char *d; char *m; int y,z; X509_NAME_oneline(X509_get_subject_name(x), buf,sizeof buf); BIO_printf(STDout,"/* subject:%s */\n",buf); m=X509_NAME_oneline( X509_get_issuer_name(x),buf, sizeof buf); BIO_printf(STDout,"/* issuer :%s */\n",buf); z=i2d_X509(x,NULL); m=OPENSSL_malloc(z); d=(unsigned char *)m; z=i2d_X509_NAME(X509_get_subject_name(x),&d); BIO_printf(STDout,"unsigned char XXX_subject_name[%d]={\n",z); d=(unsigned char *)m; for (y=0; y<z; y++) { BIO_printf(STDout,"0x%02X,",d[y]); if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n"); } if (y%16 != 0) BIO_printf(STDout,"\n"); BIO_printf(STDout,"};\n"); z=i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x),&d); BIO_printf(STDout,"unsigned char XXX_public_key[%d]={\n",z); d=(unsigned char *)m; for (y=0; y<z; y++) { BIO_printf(STDout,"0x%02X,",d[y]); if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n"); } if (y%16 != 0) BIO_printf(STDout,"\n"); BIO_printf(STDout,"};\n"); z=i2d_X509(x,&d); BIO_printf(STDout,"unsigned char XXX_certificate[%d]={\n",z); d=(unsigned char *)m; for (y=0; y<z; y++) { BIO_printf(STDout,"0x%02X,",d[y]); if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n"); } if (y%16 != 0) BIO_printf(STDout,"\n"); BIO_printf(STDout,"};\n"); OPENSSL_free(m); } else if (text == i) { X509_print_ex(out,x,nmflag, certflag); } else if (startdate == i) { BIO_puts(STDout,"notBefore="); ASN1_TIME_print(STDout,X509_get_notBefore(x)); BIO_puts(STDout,"\n"); } else if (enddate == i) { BIO_puts(STDout,"notAfter="); ASN1_TIME_print(STDout,X509_get_notAfter(x)); BIO_puts(STDout,"\n"); } else if (fingerprint == i) { int j; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; if (!X509_digest(x,digest,md,&n)) { BIO_printf(bio_err,"out of memory\n"); goto end; } BIO_printf(STDout,"%s Fingerprint=", OBJ_nid2sn(EVP_MD_type(digest))); for (j=0; j<(int)n; j++) { BIO_printf(STDout,"%02X%c",md[j], (j+1 == (int)n) ?'\n':':'); } } /* should be in the library */ else if ((sign_flag == i) && (x509req == 0)) { BIO_printf(bio_err,"Getting Private key\n"); if (Upkey == NULL) { Upkey=load_key(bio_err, keyfile, keyformat, 0, passin, e, "Private key"); if (Upkey == NULL) goto end; } #ifndef OPENSSL_NO_DSA if (Upkey->type == EVP_PKEY_DSA) digest=EVP_dss1(); #endif assert(need_rand); if (!sign(x,Upkey,days,clrext,digest, extconf, extsect)) goto end; } else if (CA_flag == i) { BIO_printf(bio_err,"Getting CA Private Key\n"); if (CAkeyfile != NULL) { CApkey=load_key(bio_err, CAkeyfile, CAkeyformat, 0, passin, e, "CA Private Key"); if (CApkey == NULL) goto end; } #ifndef OPENSSL_NO_DSA if (CApkey->type == EVP_PKEY_DSA) digest=EVP_dss1(); #endif assert(need_rand); if (!x509_certify(ctx,CAfile,digest,x,xca, CApkey, CAserial,CA_createserial,days, clrext, extconf, extsect, sno)) goto end; } else if (x509req == i) { EVP_PKEY *pk; BIO_printf(bio_err,"Getting request Private Key\n"); if (keyfile == NULL) { BIO_printf(bio_err,"no request key file specified\n"); goto end; } else { pk=load_key(bio_err, keyfile, FORMAT_PEM, 0, passin, e, "request key"); if (pk == NULL) goto end; } BIO_printf(bio_err,"Generating certificate request\n"); #ifndef OPENSSL_NO_DSA if (pk->type == EVP_PKEY_DSA) digest=EVP_dss1(); #endif rq=X509_to_X509_REQ(x,pk,digest); EVP_PKEY_free(pk); if (rq == NULL) { ERR_print_errors(bio_err); goto end; } if (!noout) { X509_REQ_print(out,rq); PEM_write_bio_X509_REQ(out,rq); } noout=1; } else if (ocspid == i) { X509_ocspid_print(out, x); } } } if (checkend) { time_t tnow=time(NULL); if (ASN1_UTCTIME_cmp_time_t(X509_get_notAfter(x), tnow+checkoffset) == -1) { BIO_printf(out,"Certificate will expire\n"); ret=1; } else { BIO_printf(out,"Certificate will not expire\n"); ret=0; } goto end; } if (noout) { ret=0; goto end; } if (outformat == FORMAT_ASN1) i=i2d_X509_bio(out,x); else if (outformat == FORMAT_PEM) { if (trustout) i=PEM_write_bio_X509_AUX(out,x); else i=PEM_write_bio_X509(out,x); } else if (outformat == FORMAT_NETSCAPE) { ASN1_HEADER ah; ASN1_OCTET_STRING os; os.data=(unsigned char *)NETSCAPE_CERT_HDR; os.length=strlen(NETSCAPE_CERT_HDR); ah.header= &os; ah.data=(char *)x; ah.meth=X509_asn1_meth(); /* no macro for this one yet */ i=ASN1_i2d_bio(i2d_ASN1_HEADER,out,(unsigned char *)&ah); } else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err,"unable to write certificate\n"); ERR_print_errors(bio_err); goto end; } ret=0; end: if (need_rand) app_RAND_write_file(NULL, bio_err); OBJ_cleanup(); NCONF_free(extconf); BIO_free_all(out); BIO_free_all(STDout); X509_STORE_free(ctx); X509_REQ_free(req); X509_free(x); X509_free(xca); EVP_PKEY_free(Upkey); EVP_PKEY_free(CApkey); X509_REQ_free(rq); ASN1_INTEGER_free(sno); sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free); sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); if (passin) OPENSSL_free(passin); apps_shutdown(); OPENSSL_EXIT(ret); }
bool Pkcs7SignedData::verify(bool checkSignerCert, vector<Certificate> trustedCerts, CertPathValidatorResult **cpvr, vector<ValidationFlags> vflags) { BIO *p7bio; bool ret; int rc; int i; int flags = 0; X509_STORE *store = NULL; STACK_OF(X509) *certs = NULL; OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); if(checkSignerCert) { i=OBJ_obj2nid(this->pkcs7->type); switch (i) { case NID_pkcs7_signed: certs = this->pkcs7->d.sign->cert; break; case NID_pkcs7_signedAndEnveloped: certs = this->pkcs7->d.signed_and_enveloped->cert; break; default: throw Pkcs7Exception(Pkcs7Exception::INVALID_TYPE, "Pkcs7SignedData::verify"); } //instancia store de certificados if(!(store = X509_STORE_new())) { throw Pkcs7Exception(Pkcs7Exception::INTERNAL_ERROR, "Pkcs7SignedData::verify"); } //define funcao de callback X509_STORE_set_verify_cb_func(store, Pkcs7SignedData::callback); //define certificados confiaveis for(unsigned int i = 0 ; i < trustedCerts.size(); i++) { X509_STORE_add_cert(store, trustedCerts.at(i).getX509()); } //define flags for(unsigned int i = 0 ; i < vflags.size() ; i++) { switch(vflags.at(i)) { case CRL_CHECK: X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK); break; case CRL_CHECK_ALL: /*precisa por CRL_CHECK tambem, caso contrario o openssl nao verifica CRL*/ X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK); X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK_ALL); break; } } /* if( (sk_X509_CRL_num(this->pkcs7->d.sign->crl) > 0) || (sk_X509_CRL_num(this->pkcs7->d.signed_and_enveloped->crl) > 0 )) { //X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); //obriga a haver uma crl para cada nivel da cadeia de certificacao X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK); } */ } else { flags = PKCS7_NOVERIFY; } p7bio = PKCS7_dataInit(this->pkcs7, NULL); rc = PKCS7_verify(this->pkcs7, certs, store, p7bio, NULL, flags); if (rc == 1) { ret = true; } else { //this case can be a error ret = false; if(cpvr) { *cpvr = new CertPathValidatorResult(Pkcs7SignedData::cpvr); } } /*desaloca estruturas*/ BIO_free(p7bio); X509_STORE_free(store); return ret; }
int main(int argc, char *argv[]) { X509 *cert; X509 *cacert; X509_CRL *crl; X509_STORE *store; X509_LOOKUP *lookup; X509_STORE_CTX *verify_ctx; STACK_OF(X509) *untrusted; STACK_OF(X509_CRL) *crls; FILE *fp; OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); /* read the client certificate */ if (!(fp = fopen(CLIENT_CERT, "r"))) { int_error("Error reading client certificate file"); } if (!(cert = PEM_read_X509(fp, NULL, NULL, NULL))) { int_error("Error reading client certificate in file"); } fclose(fp); /* read CA certificate */ if (!(fp = fopen(CA_FILE, "r"))) { int_error("Error reading CA certificate file"); } if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) { int_error("Error reading CA certificate in file"); } fclose(fp); // Read CRL if (!(fp = fopen(CRL_FILE, "r"))) { int_error("Error opening CRL file"); } if (!(crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL))) { int_error("Error reading CRL"); } fclose(fp); /* create the cert store and set the verify callback */ if (!(store = X509_STORE_new())) { int_error("Error creating X509_STORE_CTX object"); } // Add CA cert to Store if (X509_STORE_add_cert(store, cacert) != 1) { int_error("Error adding CA certificate to certificate store"); } // Add CRL to Store if (X509_STORE_add_crl(store, crl) != 1) { int_error("Error adding CRL to certificate store"); } X509_STORE_set_verify_cb_func(store, verify_callback); /* set the flags of the store so that the CRLs are consulted */ X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); // Create an empty X509_Stack for untrusted if (!(untrusted = sk_X509_new_null())) { int_error("Error creating X509_Stack"); } // Create a CRL_Stack if (!(crls = sk_X509_CRL_new_null())) { int_error("Error creating X509_CRL"); } // Add CRL to CRL_Stack if (sk_X509_CRL_push(crls, crl) != 1) { int_error("Error adding a CRL to the Stack of CRLs"); } /* create a verification context and initialize it */ if (!(verify_ctx = X509_STORE_CTX_new())) { int_error("Error creating X509_STORE_CTX object"); } // We are explicitly adding an empty X509_Stack for untrusted if (X509_STORE_CTX_init(verify_ctx, store, cert, untrusted) != 1) { int_error("Error initializing verification context"); } X509_STORE_CTX_set0_crls(verify_ctx, crls); /* verify the certificate */ if (X509_verify_cert(verify_ctx) != 1) { int_error("Error verifying the certificate"); } else { printf("Certificate verified correctly!\n"); } return 0; }