bool bdoc::X509Cert::verify(X509_STORE* aStore, struct tm* tm) const { if (aStore == NULL) { THROW_STACK_EXCEPTION("Invalid argument to verify"); } X509_STORE* store = aStore; X509_STORE** ppStore = NULL; X509_STORE_scope xst(ppStore); X509_STORE_CTX *csc = X509_STORE_CTX_new(); X509_STORE_CTX_scope csct(&csc); if (csc == NULL) { THROW_STACK_EXCEPTION("Failed to create X509_STORE_CTX %s",ERR_reason_error_string(ERR_get_error())); } X509* x = getX509(); X509_scope xt(&x); if (!X509_STORE_CTX_init(csc, store, x, NULL)) { THROW_STACK_EXCEPTION("Failed to init X509_STORE_CTX %s",ERR_reason_error_string(ERR_get_error())); } if (tm != NULL) { time_t t = timegm(tm); if (t == -1) { THROW_STACK_EXCEPTION("Given time cannot be represented as calendar time"); } X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(csc); if (param == NULL) { THROW_STACK_EXCEPTION("Failed to retrieve X509_STORE_CTX verification parameters %s", ERR_reason_error_string(ERR_get_error())); } X509_VERIFY_PARAM_set_time(param, t); } int ok = X509_verify_cert(csc); if (ok != 1) { int err = X509_STORE_CTX_get_error(csc); X509Cert cause(X509_STORE_CTX_get_current_cert (csc)); std::ostringstream s; s << "Unable to verify " << cause.getSubject(); s << ". Cause: " << X509_verify_cert_error_string(err); switch (err) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: { THROW_STACK_EXCEPTION("Certificate issuer missing: %s", s.str().c_str()); } default: THROW_STACK_EXCEPTION(s.str().c_str()); break; } } return (ok == 1); }
/** * Check if X509Cert is signed by trusted issuer * @param aStore X509_STORE of trusted issuers. If NULL, lib uses X509CertStore::getInstance()->getCertStore() * @return 0 or openssl error_code. Get human readable cause with X509_verify_cert_error_string(code) * @throw IOException if error */ int digidoc::X509Cert::verify(X509_STORE* aStore) const throw(IOException) { X509_STORE* store = aStore; X509_STORE** ppStore = NULL; if(store == NULL) { store = digidoc::X509CertStore::getInstance()->getCertStore(); ppStore = &store;//init ppStore to newly created store, so X509_STORE_scope can free it } X509_STORE_scope xst(ppStore); X509_STORE_CTX *csc = X509_STORE_CTX_new(); X509_STORE_CTX_scope csct(&csc); if (csc == NULL) { THROW_IOEXCEPTION("Failed to create X509_STORE_CTX %s",ERR_reason_error_string(ERR_get_error())); } X509* x = getX509(); X509_scope xt(&x); if(!X509_STORE_CTX_init(csc, store, x, NULL)) { THROW_IOEXCEPTION("Failed to init X509_STORE_CTX %s",ERR_reason_error_string(ERR_get_error())); } int ok = X509_verify_cert(csc); if(!ok) { int err = X509_STORE_CTX_get_error(csc); X509Cert cause(X509_STORE_CTX_get_current_cert (csc)); std::ostringstream s; s << "Unable to verify " << cause.getSubjectName(); s << ". Cause: " << X509_verify_cert_error_string(err); switch(err) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: { IOException e(__FILE__, __LINE__, s.str()); e.setCode( Exception::CertificateIssuerMissing ); throw e; break; } default: THROW_IOEXCEPTION(s.str().c_str()); break; } } return ok; }