From 5506a74e1b033776ad441b4554716cdcfa88fe03 Mon Sep 17 00:00:00 2001 From: Reiner Herrmann Date: Sat, 28 Jul 2018 23:26:17 +0200 Subject: [PATCH] Port to OpenSSL 1.1 --- crypto/wvcrl.cc | 38 +++++++++++++------------------------- crypto/wvdiffiehellman.cc | 30 +++++++++++++++++++----------- crypto/wvdigest.cc | 16 ++++++++-------- crypto/wvocsp.cc | 35 +++++++++-------------------------- crypto/wvx509.cc | 31 ++++++++++++++++--------------- crypto/wvx509mgr.cc | 27 ++++++++++++++++----------- include/wvdiffiehellman.h | 2 +- include/wvdigest.h | 14 ++++++-------- include/wvtripledes.h | 10 +++++----- 9 files changed, 93 insertions(+), 110 deletions(-) diff --git a/crypto/wvcrl.cc b/crypto/wvcrl.cc index fa00c760..880ad85d 100644 --- a/crypto/wvcrl.cc +++ b/crypto/wvcrl.cc @@ -357,31 +357,19 @@ bool WvCRL::isrevoked(WvStringParm serial_number) const ASN1_INTEGER *serial = serial_to_int(serial_number); if (serial) { - X509_REVOKED mayberevoked; - mayberevoked.serialNumber = serial; - if (crl->crl->revoked) - { - int idx = sk_X509_REVOKED_find(crl->crl->revoked, - &mayberevoked); - ASN1_INTEGER_free(serial); - if (idx >= 0) - { - debug("Certificate is revoked.\n"); - return true; - } - else - { - debug("Certificate is not revoked.\n"); - return false; - } - } - else - { - ASN1_INTEGER_free(serial); - debug("CRL does not have revoked list.\n"); - return false; - } - + X509_REVOKED *revoked_entry = NULL; + int idx = X509_CRL_get0_by_serial(crl, &revoked_entry, serial); + ASN1_INTEGER_free(serial); + if (idx >= 1 || revoked_entry) + { + debug("Certificate is revoked.\n"); + return true; + } + else + { + debug("Certificate is not revoked.\n"); + return false; + } } else debug(WvLog::Warning, "Can't convert serial number to ASN1 format. " diff --git a/crypto/wvdiffiehellman.cc b/crypto/wvdiffiehellman.cc index 7c0bf329..15cd1040 100644 --- a/crypto/wvdiffiehellman.cc +++ b/crypto/wvdiffiehellman.cc @@ -39,24 +39,25 @@ WvDiffieHellman::WvDiffieHellman(const unsigned char *_key, int _keylen, { int problems; int check; - { + info = DH_new(); - info->p = BN_bin2bn(_key, _keylen, NULL); + BIGNUM *p = BN_bin2bn(_key, _keylen, NULL); // info->p->top = 0; // info->p->dmax = _keylen * 8 / BN_BITS2; // info->p->neg = 0; // info->p->flags = 0; - info->g = BN_new(); - BN_set_word(info->g, generator); + BIGNUM *g = BN_new(); + BN_set_word(g, generator); // info->g->d = &generator; // info->g->top = 0; // info->g->dmax = 1; // info->g->neg = 0; // info->g->flags = 0; - } - check = BN_mod_word(info->p, 24); + DH_set0_pqg(info, p, NULL, g); + + check = BN_mod_word(p, 24); DH_check(info, &problems); if (problems & DH_CHECK_P_NOT_PRIME) log(WvLog::Error, "Using a composite number for authentication.\n"); @@ -64,7 +65,7 @@ WvDiffieHellman::WvDiffieHellman(const unsigned char *_key, int _keylen, log(WvLog::Error,"Using an unsafe prime number for authentication.\n"); if (problems & DH_NOT_SUITABLE_GENERATOR) log(WvLog::Error, "Can you just use 2 instead of %s (%s)!!\n", - BN_bn2hex(info->g), check); + BN_bn2hex(g), check); if (problems & DH_UNABLE_TO_CHECK_GENERATOR) log(WvLog::Notice, "Using a strange argument for diffie-hellman.\n"); DH_generate_key(info); @@ -72,18 +73,23 @@ WvDiffieHellman::WvDiffieHellman(const unsigned char *_key, int _keylen, int WvDiffieHellman::pub_key_len() { - return BN_num_bytes(info->pub_key); + const BIGNUM *pub_key = NULL; + DH_get0_key(info, &pub_key, NULL); + return BN_num_bytes(pub_key); } int WvDiffieHellman::get_public_value(WvBuf &outbuf, int len) { - int key_len = BN_num_bytes(info->pub_key); + const BIGNUM *pub_key = NULL; + DH_get0_key(info, &pub_key, NULL); + + int key_len = BN_num_bytes(pub_key); if (key_len < len) len = key_len; // alloca is stack allocated, don't free it. unsigned char *foo = (unsigned char*)alloca(key_len); - BN_bn2bin(info->pub_key, foo); + BN_bn2bin(pub_key, foo); outbuf.put(foo, len); return len; @@ -91,8 +97,10 @@ int WvDiffieHellman::get_public_value(WvBuf &outbuf, int len) bool WvDiffieHellman::create_secret(WvBuf &inbuf, size_t in_len, WvBuf& outbuf) { + const BIGNUM *pub_key = NULL; + DH_get0_key(info, &pub_key, NULL); unsigned char *foo = (unsigned char *)alloca(DH_size(info)); - log("My public value\n%s\nYour public value\n%s\n",BN_bn2hex(info->pub_key), + log("My public value\n%s\nYour public value\n%s\n",BN_bn2hex(pub_key), hexdump_buffer(inbuf.peek(0, in_len), in_len, false)); int len = DH_compute_key (foo, BN_bin2bn(inbuf.get(in_len), in_len, NULL), info); diff --git a/crypto/wvdigest.cc b/crypto/wvdigest.cc index 150edeea..73ebb5d4 100644 --- a/crypto/wvdigest.cc +++ b/crypto/wvdigest.cc @@ -13,10 +13,10 @@ /***** WvEVPMDDigest *****/ -WvEVPMDDigest::WvEVPMDDigest(const env_md_st *_evpmd) : +WvEVPMDDigest::WvEVPMDDigest(const EVP_MD*_evpmd) : evpmd(_evpmd), active(false) { - evpctx = new EVP_MD_CTX; + evpctx = EVP_MD_CTX_new(); _reset(); } @@ -24,7 +24,7 @@ WvEVPMDDigest::WvEVPMDDigest(const env_md_st *_evpmd) : WvEVPMDDigest::~WvEVPMDDigest() { cleanup(); - delete evpctx; + EVP_MD_CTX_free(evpctx); } @@ -60,7 +60,7 @@ bool WvEVPMDDigest::_reset() // the typecast is necessary for API compatibility with different // versions of openssl. None of them *actually* change the contents of // the pointer. - EVP_DigestInit(evpctx, (env_md_st *)evpmd); + EVP_DigestInit(evpctx, evpmd); active = true; return true; } @@ -79,7 +79,7 @@ void WvEVPMDDigest::cleanup() size_t WvEVPMDDigest::digestsize() const { - return EVP_MD_size((env_md_st *)evpmd); + return EVP_MD_size(evpmd); } @@ -104,14 +104,14 @@ WvHMACDigest::WvHMACDigest(WvEVPMDDigest *_digest, { key = new unsigned char[keysize]; memcpy(key, _key, keysize); - hmacctx = new HMAC_CTX; + hmacctx = HMAC_CTX_new(); _reset(); } WvHMACDigest::~WvHMACDigest() { cleanup(); - delete hmacctx; + HMAC_CTX_free(hmacctx); deletev key; delete digest; } @@ -145,7 +145,7 @@ bool WvHMACDigest::_finish(WvBuf &outbuf) bool WvHMACDigest::_reset() { cleanup(); - HMAC_Init(hmacctx, key, keysize, (env_md_st *)digest->getevpmd()); + HMAC_Init(hmacctx, key, keysize, digest->getevpmd()); active = true; return true; } diff --git a/crypto/wvocsp.cc b/crypto/wvocsp.cc index ddb2de49..7d5da072 100644 --- a/crypto/wvocsp.cc +++ b/crypto/wvocsp.cc @@ -118,9 +118,10 @@ bool WvOCSPResp::check_nonce(const WvOCSPReq &req) const bool WvOCSPResp::signedbycert(const WvX509 &cert) const { - EVP_PKEY *skey = X509_get_pubkey(cert.cert); - int i = OCSP_BASICRESP_verify(bs, skey, 0); - EVP_PKEY_free(skey); + STACK_OF(X509) *sk = sk_X509_new_null(); + sk_X509_push(sk, cert.cert); + int i = OCSP_basic_verify(bs, sk, NULL, OCSP_NOVERIFY); + sk_X509_free(sk); if(i > 0) return true; @@ -131,33 +132,15 @@ bool WvOCSPResp::signedbycert(const WvX509 &cert) const WvX509 WvOCSPResp::get_signing_cert() const { - if (!bs || !sk_X509_num(bs->certs)) + const STACK_OF(X509) *certs = OCSP_resp_get0_certs(bs); + if (!bs || !sk_X509_num(certs)) return WvX509(); - // note: the following bit of code is taken almost verbatim from - // ocsp_vfy.c in OpenSSL 0.9.8. Copyright and attribution should - // properly belong to them - - OCSP_RESPID *id = bs->tbsResponseData->responderId; - - if (id->type == V_OCSP_RESPID_NAME) - { - X509 *x = X509_find_by_subject(bs->certs, id->value.byName); - if (x) - return WvX509(X509_dup(x)); + X509 *signer = NULL; + if (OCSP_resp_get0_signer(bs, &signer, NULL) == 1) { + return WvX509(X509_dup(signer)); } - if (id->value.byKey->length != SHA_DIGEST_LENGTH) return NULL; - unsigned char tmphash[SHA_DIGEST_LENGTH]; - unsigned char *keyhash = id->value.byKey->data; - for (int i = 0; i < sk_X509_num(bs->certs); i++) - { - X509 *x = sk_X509_value(bs->certs, i); - X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); - if(!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) - return WvX509(X509_dup(x)); - } - return WvX509(); } diff --git a/crypto/wvx509.cc b/crypto/wvx509.cc index 93dae06f..eed6c18e 100644 --- a/crypto/wvx509.cc +++ b/crypto/wvx509.cc @@ -974,7 +974,7 @@ static void add_aia(WvStringParm type, WvString identifier, sk_ACCESS_DESCRIPTION_push(ainfo, acc); acc->method = OBJ_txt2obj(type.cstr(), 0); acc->location->type = GEN_URI; - acc->location->d.ia5 = M_ASN1_IA5STRING_new(); + acc->location->d.ia5 = ASN1_IA5STRING_new(); unsigned char *cident = reinterpret_cast(identifier.edit()); ASN1_STRING_set(acc->location->d.ia5, cident, identifier.len()); @@ -1059,7 +1059,7 @@ void WvX509::set_crl_urls(WvStringList &urls) GENERAL_NAMES *uris = GENERAL_NAMES_new(); GENERAL_NAME *uri = GENERAL_NAME_new(); uri->type = GEN_URI; - uri->d.ia5 = M_ASN1_IA5STRING_new(); + uri->d.ia5 = ASN1_IA5STRING_new(); unsigned char *cident = reinterpret_cast(i().edit()); ASN1_STRING_set(uri->d.ia5, cident, i().len()); @@ -1158,10 +1158,11 @@ WvString WvX509::get_extension(int nid) const if (ext) { X509V3_EXT_METHOD *method = (X509V3_EXT_METHOD *) X509V3_EXT_get(ext); + ASN1_OCTET_STRING *ext_data_str = X509_EXTENSION_get_data(ext); if (!method) { WvDynBuf buf; - buf.put(ext->value->data, ext->value->length); + buf.put(ext_data_str->data, ext_data_str->length); retval = buf.getstr(); } else @@ -1172,21 +1173,21 @@ WvString WvX509::get_extension(int nid) const // even though it's const (at least as of version 0.9.8e). // gah. #if OPENSSL_VERSION_NUMBER >= 0x0090800fL - const unsigned char * ext_value_data = ext->value->data; + const unsigned char * ext_value_data = ext_data_str->data; #else unsigned char *ext_value_data = ext->value->data; #endif if (method->it) { ext_data = ASN1_item_d2i(NULL, &ext_value_data, - ext->value->length, + ext_data_str->length, ASN1_ITEM_ptr(method->it)); TRACE("Applied generic conversion!\n"); } else { ext_data = method->d2i(NULL, &ext_value_data, - ext->value->length); + ext_data_str->length); TRACE("Applied method specific conversion!\n"); } @@ -1321,13 +1322,13 @@ bool WvX509::verify(WvBuf &original, WvStringParm signature) const return false; /* Verify the signature */ - EVP_MD_CTX sig_ctx; - EVP_VerifyInit(&sig_ctx, EVP_sha1()); - EVP_VerifyUpdate(&sig_ctx, original.peek(0, original.used()), + EVP_MD_CTX *sig_ctx = EVP_MD_CTX_new(); + EVP_VerifyInit(sig_ctx, EVP_sha1()); + EVP_VerifyUpdate(sig_ctx, original.peek(0, original.used()), original.used()); - int sig_err = EVP_VerifyFinal(&sig_ctx, sig_buf, sig_size, pk); + int sig_err = EVP_VerifyFinal(sig_ctx, sig_buf, sig_size, pk); EVP_PKEY_free(pk); - EVP_MD_CTX_cleanup(&sig_ctx); // Again, not my fault... + EVP_MD_CTX_free(sig_ctx); // Again, not my fault... if (sig_err != 1) { debug("Verify failed!\n"); @@ -1446,19 +1447,19 @@ void WvX509::set_ski() { CHECK_CERT_EXISTS_SET("ski"); - ASN1_OCTET_STRING *oct = M_ASN1_OCTET_STRING_new(); - ASN1_BIT_STRING *pk = cert->cert_info->key->public_key; + ASN1_OCTET_STRING *oct = ASN1_OCTET_STRING_new(); + ASN1_BIT_STRING *pk = X509_get0_pubkey_bitstr(cert); unsigned char pkey_dig[EVP_MAX_MD_SIZE]; unsigned int diglen; EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL); - M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen); + ASN1_OCTET_STRING_set(oct, pkey_dig, diglen); X509_EXTENSION *ext = X509V3_EXT_i2d(NID_subject_key_identifier, 0, oct); X509_add_ext(cert, ext, -1); X509_EXTENSION_free(ext); - M_ASN1_OCTET_STRING_free(oct); + ASN1_OCTET_STRING_free(oct); } diff --git a/crypto/wvx509mgr.cc b/crypto/wvx509mgr.cc index f249eeca..156d3a49 100644 --- a/crypto/wvx509mgr.cc +++ b/crypto/wvx509mgr.cc @@ -350,6 +350,8 @@ bool WvX509Mgr::signcert(WvX509 &unsignedcert) const return false; } + uint32_t ex_flags = X509_get_extension_flags(cert); + uint32_t ex_kusage = X509_get_key_usage(cert); if (cert == unsignedcert.cert) { debug("Self Signing!\n"); @@ -362,8 +364,8 @@ bool WvX509Mgr::signcert(WvX509 &unsignedcert) const return false; } #endif - else if (!((cert->ex_flags & EXFLAG_KUSAGE) && - (cert->ex_kusage & KU_KEY_CERT_SIGN))) + else if (!((ex_flags & EXFLAG_KUSAGE) && + (ex_kusage & KU_KEY_CERT_SIGN))) { debug("This Certificate is not allowed to sign certificates!\n"); return false; @@ -390,6 +392,8 @@ bool WvX509Mgr::signcert(WvX509 &unsignedcert) const bool WvX509Mgr::signcrl(WvCRL &crl) const { + uint32_t ex_flags = X509_get_extension_flags(cert); + uint32_t ex_kusage = X509_get_key_usage(cert); if (!isok() || !crl.isok()) { debug(WvLog::Warning, "Asked to sign CRL, but certificate or CRL (or " @@ -403,12 +407,12 @@ bool WvX509Mgr::signcrl(WvCRL &crl) const "CRLs!\n"); return false; } - else if (!((cert->ex_flags & EXFLAG_KUSAGE) && - (cert->ex_kusage & KU_CRL_SIGN))) + else if (!((ex_flags & EXFLAG_KUSAGE) && + (ex_kusage & KU_CRL_SIGN))) { debug("Certificate not allowed to sign CRLs! (%s %s)\n", - (cert->ex_flags & EXFLAG_KUSAGE), - (cert->ex_kusage & KU_CRL_SIGN)); + (ex_flags & EXFLAG_KUSAGE), + (ex_kusage & KU_CRL_SIGN)); return false; } #endif @@ -454,7 +458,6 @@ WvString WvX509Mgr::sign(WvBuf &data) const { assert(rsa); - EVP_MD_CTX sig_ctx; unsigned char sig_buf[4096]; EVP_PKEY *pk = EVP_PKEY_new(); @@ -467,20 +470,22 @@ WvString WvX509Mgr::sign(WvBuf &data) const return WvString::null; } - EVP_SignInit(&sig_ctx, EVP_sha1()); - EVP_SignUpdate(&sig_ctx, data.peek(0, data.used()), data.used()); + EVP_MD_CTX *sig_ctx = EVP_MD_CTX_new(); + EVP_SignInit(sig_ctx, EVP_sha1()); + EVP_SignUpdate(sig_ctx, data.peek(0, data.used()), data.used()); unsigned int sig_len = sizeof(sig_buf); - int sig_err = EVP_SignFinal(&sig_ctx, sig_buf, + int sig_err = EVP_SignFinal(sig_ctx, sig_buf, &sig_len, pk); if (sig_err != 1) { debug("Error while signing.\n"); EVP_PKEY_free(pk); + EVP_MD_CTX_free(sig_ctx); return WvString::null; } EVP_PKEY_free(pk); - EVP_MD_CTX_cleanup(&sig_ctx); // this isn't my fault :// + EVP_MD_CTX_free(sig_ctx); // this isn't my fault :// WvDynBuf buf; buf.put(sig_buf, sig_len); debug("Signature size: %s\n", buf.used()); diff --git a/include/wvdiffiehellman.h b/include/wvdiffiehellman.h index af75ffa9..a2d001f8 100644 --- a/include/wvdiffiehellman.h +++ b/include/wvdiffiehellman.h @@ -27,7 +27,7 @@ class WvDiffieHellman bool create_secret(WvBuf &inbuf, size_t in_len, WvBuf& outbuf); protected: - struct dh_st *info; + DH *info; BN_ULONG generator; private: diff --git a/include/wvdigest.h b/include/wvdigest.h index fdc39bd6..f2eed401 100644 --- a/include/wvdigest.h +++ b/include/wvdigest.h @@ -9,10 +9,8 @@ #include "wvencoder.h" #include +#include -struct env_md_st; -struct env_md_ctx_st; -struct hmac_ctx_st; /** * Superclass for all message digests. @@ -45,8 +43,8 @@ class WvDigest : public WvEncoder class WvEVPMDDigest : public WvDigest { friend class WvHMACDigest; - const env_md_st *evpmd; - env_md_ctx_st *evpctx; + const EVP_MD *evpmd; + EVP_MD_CTX *evpctx; bool active; public: @@ -54,13 +52,13 @@ class WvEVPMDDigest : public WvDigest virtual size_t digestsize() const; protected: - WvEVPMDDigest(const env_md_st *_evpmd); + WvEVPMDDigest(const EVP_MD *_evpmd); virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush); // consumes input virtual bool _finish(WvBuf &outbuf); // outputs digest virtual bool _reset(); // supported: resets digest value - const env_md_st *getevpmd() + const EVP_MD *getevpmd() { return evpmd; } private: @@ -104,7 +102,7 @@ class WvHMACDigest : public WvDigest WvEVPMDDigest *digest; unsigned char *key; size_t keysize; - hmac_ctx_st *hmacctx; + HMAC_CTX *hmacctx; bool active; public: diff --git a/include/wvtripledes.h b/include/wvtripledes.h index 185fe8a9..a442e7a0 100644 --- a/include/wvtripledes.h +++ b/include/wvtripledes.h @@ -70,11 +70,11 @@ class WvTripleDESEncoder : public WvCryptoEncoder private: Mode mode; - des_cblock key; - des_key_schedule deskey1; - des_key_schedule deskey2; - des_key_schedule deskey3; - des_cblock ivec; // initialization vector + DES_cblock key; + DES_key_schedule deskey1; + DES_key_schedule deskey2; + DES_key_schedule deskey3; + DES_cblock ivec; // initialization vector int ivecoff; // current offset into initvec };