Blob Blame History Raw
diff -Naur libdigidocpp-3.12.3_orig/src/crypto/Connect.cpp libdigidocpp-3.12.3_patched/src/crypto/Connect.cpp
--- libdigidocpp-3.12.3_orig/src/crypto/Connect.cpp	2017-02-14 16:42:06.000000000 +0200
+++ libdigidocpp-3.12.3_patched/src/crypto/Connect.cpp	2017-02-25 00:17:17.213752854 +0200
@@ -29,6 +29,7 @@
 
 #include <zlib.h>
 
+#include <cstring>
 #include <thread>
 
 using namespace digidoc;
@@ -104,7 +105,8 @@
         {
             SSL_CTX_set_verify(ssl.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
             SSL_CTX_set_cert_verify_callback(ssl.get(), [](X509_STORE_CTX *store, void *cert) -> int {
-                return store->cert && X509_cmp(store->cert, (X509*)cert) == 0 ? 1 : 0;
+                X509 *x509 = X509_STORE_CTX_get0_cert(store);
+                return x509 && X509_cmp(x509, (X509*)cert) == 0 ? 1 : 0;
             }, cert.handle());
         }
         BIO *sbio = BIO_new_ssl(ssl.get(), 1);
diff -Naur libdigidocpp-3.12.3_orig/src/crypto/Digest.cpp libdigidocpp-3.12.3_patched/src/crypto/Digest.cpp
--- libdigidocpp-3.12.3_orig/src/crypto/Digest.cpp	2017-02-14 16:42:06.000000000 +0200
+++ libdigidocpp-3.12.3_patched/src/crypto/Digest.cpp	2017-02-24 23:57:24.672462506 +0200
@@ -89,7 +89,9 @@
     SCOPE(X509_SIG, sig, d2i_X509_SIG(NULL, &p, (long)digest.size()));
     if(!sig)
         return vector<unsigned char>();
-    return vector<unsigned char>(sig->digest->data, sig->digest->data + sig->digest->length);
+    const ASN1_OCTET_STRING *value = nullptr;
+    X509_SIG_get0(sig.get(), nullptr, &value);
+    return vector<unsigned char>(value->data, value->data + value->length);
 }
 
 string Digest::digestInfoUri(const std::vector<unsigned char> &digest)
@@ -98,7 +100,9 @@
     SCOPE(X509_SIG, sig, d2i_X509_SIG(NULL, &p, (long)digest.size()));
     if(!sig)
         return string();
-    switch(OBJ_obj2nid(sig->algor->algorithm))
+    const X509_ALGOR *algor = nullptr;
+    X509_SIG_get0(sig.get(), &algor, nullptr);
+    switch(OBJ_obj2nid(algor->algorithm))
     {
     case NID_sha1:  return URI_SHA1;
     case NID_sha224: return URI_SHA224;
diff -Naur libdigidocpp-3.12.3_orig/src/crypto/OCSP.cpp libdigidocpp-3.12.3_patched/src/crypto/OCSP.cpp
--- libdigidocpp-3.12.3_orig/src/crypto/OCSP.cpp	2017-02-14 16:42:06.000000000 +0200
+++ libdigidocpp-3.12.3_patched/src/crypto/OCSP.cpp	2017-02-24 23:57:41.151494155 +0200
@@ -131,20 +131,19 @@
 {
     if(!basic || !cert)
         return false;
-    OCSP_RESPID *respID =  basic->tbsResponseData->responderId;
-    switch(respID->type)
-    {
-    case V_OCSP_RESPID_NAME:
-        return X509_NAME_cmp(X509_get_subject_name(cert.handle()), respID->value.byName) == 0;
-    case V_OCSP_RESPID_KEY:
+    const ASN1_OCTET_STRING *hash = nullptr;
+    const X509_NAME *name = nullptr;
+    OCSP_resp_get0_id(basic, &hash, &name);
+    if(name)
+        return X509_NAME_cmp(X509_get_subject_name(cert.handle()), name) == 0;
+    else if(hash)
     {
         unsigned char sha1[SHA_DIGEST_LENGTH];
-        ASN1_BIT_STRING *key = cert.handle()->cert_info->key->public_key;
+        ASN1_BIT_STRING *key = X509_get0_pubkey_bitstr(cert.handle());
         return EVP_Digest(key->data, key->length, sha1, nullptr, EVP_sha1(), nullptr) == 1 &&
-            memcmp(respID->value.byKey->data, &sha1, respID->value.byKey->length) == 0;
-    }
-    default: return false;
+            memcmp(hash->data, &sha1, hash->length) == 0;
     }
+    return false;
 }
 
 /**
@@ -169,7 +168,7 @@
     if(OCSP_request_add1_nonce(req.get(), const_cast<unsigned char*>(&nonce[0]), int(nonce.size())) <= 0)
         THROW_OPENSSLEXCEPTION("Failed to add NONCE to OCSP request.");
 #else
-    ASN1_OCTET_STRING *st = M_ASN1_OCTET_STRING_new();
+    ASN1_OCTET_STRING *st = ASN1_OCTET_STRING_new();
     if(nonce.empty())
     {
         st->length = 20;
@@ -182,7 +181,7 @@
         st->length = int(nonce.size());
     }
     X509_EXTENSION *ex = X509_EXTENSION_create_by_NID(0, NID_id_pkix_OCSP_Nonce, 0, st);
-    if(!X509v3_add_ext(&req->tbsRequest->requestExtensions, ex, 0))
+    if(!OCSP_REQUEST_add_ext(req.get(), ex, 0))
         THROW_OPENSSLEXCEPTION("Failed to add NONCE to OCSP request.");
 #endif
 
@@ -266,9 +265,10 @@
 {
     if(!basic)
         return X509Cert();
-    for(int i = 0; i < sk_X509_num(basic->certs); ++i)
+    const STACK_OF(X509) *certs = OCSP_resp_get0_certs(basic);
+    for(int i = 0; i < sk_X509_num(certs); ++i)
     {
-        X509Cert cert(sk_X509_value(basic->certs, i));
+        X509Cert cert(sk_X509_value(certs, i));
         if(compareResponderCert(cert))
             return cert;
     }
@@ -419,8 +419,9 @@
         case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
         case X509_V_ERR_CERT_UNTRUSTED:
         {
+            X509 *x509 = X509_STORE_CTX_get0_cert(ctx);
             const vector<X509Cert> &list = X509CertStore::instance()->certs();
-            if(find(list.begin(), list.end(), X509Cert(ctx->current_cert)) != list.end())
+            if(find(list.begin(), list.end(), X509Cert(x509)) != list.end())
                 return 1;
             return ok;
         }
@@ -429,7 +430,7 @@
     });
 
     tm t = util::date::ASN1TimeToTM(producedAt());
-    X509_VERIFY_PARAM_set_time(store->param, util::date::mkgmtime(t));
+    X509_VERIFY_PARAM_set_time(X509_STORE_get0_param(store.get()), util::date::mkgmtime(t));
     X509_STORE_set_flags(store.get(), X509_V_FLAG_USE_CHECK_TIME);
 
     //X509_STORE_set_trust(store.get(), X509_TRUST_TRUSTED);
@@ -492,7 +493,8 @@
     if(!ext)
         return vector<unsigned char>();
 
-    vector<unsigned char> nonce(ext->value->data, ext->value->data + ext->value->length);
+    ASN1_OCTET_STRING *value = X509_EXTENSION_get_data(ext);
+    vector<unsigned char> nonce(value->data, value->data + value->length);
 #if 1 //def OCSP_NATIVE_NONCE
     //OpenSSL OCSP created messages NID_id_pkix_OCSP_Nonce field is DER encoded twice, not a problem with java impl
     //XXX: UglyHackTM check if nonceAsn1 contains ASN1_OCTET_STRING
@@ -506,6 +508,10 @@
 
 string OCSP::producedAt() const
 {
-    ASN1_GENERALIZEDTIME* time = basic->tbsResponseData->producedAt;
-    return string(time->data, time->data+time->length);
+    string result;
+    if(!basic)
+        return result;
+    const ASN1_GENERALIZEDTIME *time = OCSP_resp_get0_produced_at(basic);
+    result.assign(time->data, time->data+time->length);
+    return result;
 }
diff -Naur libdigidocpp-3.12.3_orig/src/crypto/PKCS12Signer.cpp libdigidocpp-3.12.3_patched/src/crypto/PKCS12Signer.cpp
--- libdigidocpp-3.12.3_orig/src/crypto/PKCS12Signer.cpp	2017-02-14 16:42:06.000000000 +0200
+++ libdigidocpp-3.12.3_patched/src/crypto/PKCS12Signer.cpp	2017-02-24 23:57:59.358529122 +0200
@@ -87,7 +87,7 @@
 
     int result = 0;
     vector<unsigned char> signature;
-    switch(EVP_PKEY_type(d->key->type))
+    switch(EVP_PKEY_base_id(d->key))
     {
     case EVP_PKEY_RSA:
     {
@@ -118,9 +118,11 @@
              THROW("Error caclulating signature size");
         signature.resize(keyLen * 2);
 
-        if(BN_bn2bin(sig->r, &signature[keyLen - BN_num_bytes(sig->r)]) <= 0)
+        const BIGNUM *r = nullptr, *s = nullptr;
+        ECDSA_SIG_get0(sig.get(), &r, &s);
+        if(BN_bn2bin(r, &signature[keyLen - BN_num_bytes(r)]) <= 0)
             THROW("Error copying signature 'r' value to buffer");
-        if(BN_bn2bin(sig->s, &signature[keyLen*2 - BN_num_bytes(sig->s)]) <= 0)
+        if(BN_bn2bin(s, &signature[keyLen*2 - BN_num_bytes(s)]) <= 0)
             THROW("Error copying signature 's' value to buffer");
 
         result = 1;
diff -Naur libdigidocpp-3.12.3_orig/src/crypto/TS.cpp libdigidocpp-3.12.3_patched/src/crypto/TS.cpp
--- libdigidocpp-3.12.3_orig/src/crypto/TS.cpp	2017-02-14 16:42:06.000000000 +0200
+++ libdigidocpp-3.12.3_patched/src/crypto/TS.cpp	2017-02-24 23:58:13.666556602 +0200
@@ -86,13 +86,12 @@
         THROW_OPENSSLEXCEPTION("Failed to parse TS response.");
 
     SCOPE(TS_VERIFY_CTX, ctx, TS_VERIFY_CTX_new());
-    ctx->flags = TS_VFY_NONCE|TS_VFY_VERSION;
-    ctx->nonce = nonce.release();
+    TS_VERIFY_CTX_set_flags(ctx.get(), TS_VFY_VERSION);//|TS_VFY_NONCE);
+    //ctx->nonce = nonce.release();
     if(TS_RESP_verify_response(ctx.get(), resp.get()) != 1)
         THROW_OPENSSLEXCEPTION("Failed to verify TS response.");
 
-    d.reset(resp->token, function<void(PKCS7*)>(PKCS7_free));
-    resp->token = nullptr;
+    d.reset(PKCS7_dup(TS_RESP_get_token(resp.get())), function<void(PKCS7*)>(PKCS7_free));
 }
 
 TS::TS(const std::vector<unsigned char> &data)
@@ -122,7 +121,8 @@
     if(!d)
         return string();
     SCOPE(TS_TST_INFO, info, PKCS7_to_TS_TST_INFO(d.get()));
-    switch(OBJ_obj2nid(info->msg_imprint->hash_algo->algorithm))
+    X509_ALGOR *algo = TS_MSG_IMPRINT_get_algo(TS_TST_INFO_get_msg_imprint(info.get()));
+    switch(OBJ_obj2nid(algo->algorithm))
     {
     case NID_sha1: return URI_SHA1;
     case NID_sha224: return URI_SHA224;
@@ -140,7 +140,8 @@
     SCOPE(TS_TST_INFO, info, PKCS7_to_TS_TST_INFO(d.get()));
     if(!info)
         return string();
-    return string((char*)info->time->data, info->time->length);
+    const ASN1_GENERALIZEDTIME *time = TS_TST_INFO_get_time(info.get());
+    return info ? string((char*)time->data, size_t(time->length)) : string();
 }
 
 void TS::verify(const Digest &digest)
@@ -150,24 +151,24 @@
 
     vector<unsigned char> data = digest.result();
     SCOPE(TS_VERIFY_CTX, ctx, TS_VERIFY_CTX_new());
-    ctx->flags = TS_VFY_IMPRINT|TS_VFY_VERSION|TS_VFY_SIGNATURE;
-    ctx->imprint = data.data();
-    ctx->imprint_len = (unsigned int)data.size();
+    TS_VERIFY_CTX_set_flags(ctx.get(), TS_VFY_IMPRINT|TS_VFY_VERSION|TS_VFY_SIGNATURE);
+    TS_VERIFY_CTX_set_imprint(ctx.get(), data.data(), (long)data.size());
 
-    ctx->store = X509_STORE_new();
+    X509_STORE *store = X509_STORE_new();
     X509CertStore::instance()->activate(cert().issuerName("C"));
     for(const X509Cert &i: X509CertStore::instance()->certs())
-        X509_STORE_add_cert(ctx->store, i.handle());
+        X509_STORE_add_cert(store, i.handle());
     OpenSSLException(); // Clear errors
+    TS_VERIFY_CTX_set_store(ctx.get(), store);
 
     SCOPE(X509_STORE_CTX, csc, X509_STORE_CTX_new());
     if (!csc)
         THROW_OPENSSLEXCEPTION("Failed to create X509_STORE_CTX");
 
-    if(!X509_STORE_CTX_init(csc.get(), ctx->store, 0, 0))
+    if(!X509_STORE_CTX_init(csc.get(), store, 0, 0))
         THROW_OPENSSLEXCEPTION("Failed to init X509_STORE_CTX");
 
-    X509_STORE_set_verify_cb_func(ctx->store, [](int ok, X509_STORE_CTX *ctx) -> int {
+    X509_STORE_set_verify_cb_func(store, [](int ok, X509_STORE_CTX *ctx) -> int {
         switch(X509_STORE_CTX_get_error(ctx))
         {
         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
@@ -175,8 +176,9 @@
         case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
         case X509_V_ERR_CERT_UNTRUSTED:
         {
+            X509 *x509 = X509_STORE_CTX_get0_cert(ctx);
             const vector<X509Cert> &list = X509CertStore::instance()->certs();
-            if(find(list.begin(), list.end(), X509Cert(ctx->current_cert)) != list.end())
+            if(find(list.begin(), list.end(), X509Cert(x509)) != list.end())
                 return 1;
             return ok;
         }
@@ -185,9 +187,7 @@
     });
 
     int err = TS_RESP_verify_token(ctx.get(), d.get());
-    //Avoid CRYPTO_free
-    ctx->imprint = nullptr;
-    ctx->imprint_len = 0;
+    TS_VERIFY_CTX_set_imprint(ctx.get(), nullptr, 0); //Avoid CRYPTO_free
     if(err != 1)
     {
         long err = ERR_get_error();
diff -Naur libdigidocpp-3.12.3_orig/src/crypto/X509Cert.cpp libdigidocpp-3.12.3_patched/src/crypto/X509Cert.cpp
--- libdigidocpp-3.12.3_orig/src/crypto/X509Cert.cpp	2017-02-14 16:42:06.000000000 +0200
+++ libdigidocpp-3.12.3_patched/src/crypto/X509Cert.cpp	2017-02-24 23:58:27.935584006 +0200
@@ -374,13 +374,13 @@
     if(pos == -1)
         return result;
     X509_EXTENSION *ext = X509_get_ext(cert.get(), pos);
-    STACK_OF(QCStatement) *qc = (STACK_OF(QCStatement)*)ASN1_item_unpack(ext->value, ASN1_ITEM_rptr(QCStatements));
+    QCStatements *qc = (QCStatements*)ASN1_item_unpack(X509_EXTENSION_get_data(ext), ASN1_ITEM_rptr(QCStatements));
     if(!qc)
         return result;
 
-    for(int i = 0; i < SKM_sk_num(QCStatement, qc); ++i)
+    for(int i = 0; i < sk_num((const stack_st*)qc); ++i)
     {
-        QCStatement *s = SKM_sk_value(QCStatement, qc, i);
+        QCStatement *s = (QCStatement*)sk_value((const stack_st*)qc, i);
         string oid = toOID(s->statementId);
         if(oid == QC_SYNTAX2)
         {
@@ -413,7 +413,8 @@
         else
             result.push_back(oid);
     }
-    SKM_sk_pop_free(QCStatement, qc, QCStatement_free);
+    typedef void (*cast_free) (void *);
+    sk_pop_free((stack_st*)qc, (cast_free)QCStatement_free);
     return result;
 }
 
@@ -518,8 +519,8 @@
 {
     if(!cert)
         THROW_OPENSSLEXCEPTION("Failed to validate cert");
-    int notBefore = X509_cmp_time(cert->cert_info->validity->notBefore, t);
-    int notAfter = X509_cmp_time(cert->cert_info->validity->notAfter, t);
+    int notBefore = X509_cmp_time(X509_get0_notBefore(cert.get()), t);
+    int notAfter = X509_cmp_time(X509_get0_notAfter(cert.get()), t);
     if(notBefore == 0 || notAfter == 0)
         THROW_OPENSSLEXCEPTION("Failed to validate cert");
     return notBefore < 0 && notAfter > 0;
diff -Naur libdigidocpp-3.12.3_orig/src/crypto/X509CertStore.cpp libdigidocpp-3.12.3_patched/src/crypto/X509CertStore.cpp
--- libdigidocpp-3.12.3_orig/src/crypto/X509CertStore.cpp	2017-02-14 16:42:06.000000000 +0200
+++ libdigidocpp-3.12.3_patched/src/crypto/X509CertStore.cpp	2017-02-24 23:58:41.274609625 +0200
@@ -220,7 +220,8 @@
         case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
         case X509_V_ERR_CERT_UNTRUSTED:
         {
-            if(find(instance()->d->begin(), instance()->d->end(), X509Cert(ctx->current_cert)) != instance()->d->end())
+            X509 *x509 = X509_STORE_CTX_get0_cert(ctx);
+            if(find(instance()->d->begin(), instance()->d->end(), X509Cert(x509)) != instance()->d->end())
                 return 1;
             return ok;
         }
diff -Naur libdigidocpp-3.12.3_orig/src/crypto/X509Crypto.cpp libdigidocpp-3.12.3_patched/src/crypto/X509Crypto.cpp
--- libdigidocpp-3.12.3_orig/src/crypto/X509Crypto.cpp	2017-02-14 16:42:06.000000000 +0200
+++ libdigidocpp-3.12.3_patched/src/crypto/X509Crypto.cpp	2017-02-24 23:58:53.014632172 +0200
@@ -23,8 +23,9 @@
 #include "crypto/Digest.h"
 #include "crypto/OpenSSLHelpers.h"
 
+#include <openssl/asn1t.h>
 #include <openssl/err.h>
-#include <openssl/x509.h>
+#include <openssl/x509v3.h>
 
 #include <cstring>
 #include <set>
@@ -32,6 +33,23 @@
 using namespace digidoc;
 using namespace std;
 
+/*-
+ * IssuerSerial ::= SEQUENCE {
+ *         issuer                   GeneralNames,
+ *         serialNumber             CertificateSerialNumber
+ *         }
+ */
+typedef struct ESS_issuer_serial {
+    STACK_OF(GENERAL_NAME) *issuer;
+    ASN1_INTEGER *serial;
+} ESS_ISSUER_SERIAL;
+
+ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = {
+        ASN1_SEQUENCE_OF(ESS_ISSUER_SERIAL, issuer, GENERAL_NAME),
+        ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER)
+} static_ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL)
+IMPLEMENT_ASN1_FUNCTIONS_const(ESS_ISSUER_SERIAL)
+
 /**
  * Initialize RSA crypter.
  *
@@ -70,6 +88,17 @@
  */
 int X509Crypto::compareIssuerToString(const string &name) const
 {
+    static const std::set<std::string> list{
+        "CN", "commonName",
+        "L", "localityName",
+        "ST", "stateOrProvinceName",
+        "O", "organizationName",
+        "OU", "organizationalUnitName",
+        "C", "countryName",
+        "STREET", "streetAddress",
+        "DC", "domainComponent",
+        "UID", "userId"
+    };
     size_t old = 0;
     while(true)
     {
@@ -94,38 +123,26 @@
             continue;
 
         string obj = nameitem.substr(0, pos);
-
-        static std::set<std::string> list{"CN", "commonName",
-                                          "L", "localityName",
-                                          "ST", "stateOrProvinceName",
-                                          "O", "organizationName",
-                                          "OU", "organizationalUnitName",
-                                          "C", "countryName",
-                                          "STREET", "streetAddress",
-                                          "DC", "domainComponent",
-                                          "UID", "userId"
-                                          };
         if(list.find(obj) == list.end())
             continue;
 
-        SCOPE(X509_NAME_ENTRY, enta, X509_NAME_ENTRY_create_by_txt(0, obj.c_str(),
-            MBSTRING_UTF8, (unsigned char*)nameitem.substr(pos+1, pos-old).c_str(), -1));
-        if(!enta)
-            return -1;
-
-        ASN1_OBJECT *obja = X509_NAME_ENTRY_get_object(enta.get());
+        ASN1_OBJECT *obja = OBJ_txt2obj(obj.c_str(), 0);
+        string value = nameitem.substr(pos+1, pos-old);
 
         bool found = false;
-        for(int i = 0; i < X509_NAME_entry_count(X509_get_issuer_name(cert.handle())); ++i)
+        X509_NAME *issuer = X509_get_issuer_name(cert.handle());
+        for(int i = 0; i < X509_NAME_entry_count(issuer); ++i)
         {
-            X509_NAME_ENTRY *entb = X509_NAME_get_entry(X509_get_issuer_name(cert.handle()), i);
-            ASN1_OBJECT *objb = X509_NAME_ENTRY_get_object(entb);
-            if(memcmp(obja->data, objb->data, obja->length) == 0 &&
-                memcmp(enta->value, entb->value, enta->size) == 0)
-            {
-                found = true;
+            X509_NAME_ENTRY *entb = X509_NAME_get_entry(issuer, i);
+            if(OBJ_cmp(obja, X509_NAME_ENTRY_get_object(entb)) != 0)
+                continue;
+
+            char *data = nullptr;
+            int size = ASN1_STRING_to_UTF8((unsigned char**)&data, X509_NAME_ENTRY_get_data(entb));
+            found = value.compare(0, size_t(size), data) == 0;
+            OPENSSL_free(data);
+            if(found)
                 break;
-            }
         }
         if(!found)
             return -1;
@@ -140,16 +157,18 @@
 vector<unsigned char> X509Crypto::rsaModulus() const
 {
     SCOPE(EVP_PKEY, key, X509_get_pubkey(cert.handle()));
-    if(!key || key->type != EVP_PKEY_RSA)
+    if(!key || EVP_PKEY_base_id(key.get()) != EVP_PKEY_RSA)
         return vector<unsigned char>();
 
     SCOPE(RSA, rsa, EVP_PKEY_get1_RSA(key.get()));
-    int bufSize = BN_num_bytes(rsa->n);
+    const BIGNUM *n = nullptr;
+    RSA_get0_key(rsa.get(), &n, nullptr, nullptr);
+    int bufSize = BN_num_bytes(n);
     if(bufSize <= 0)
         return vector<unsigned char>();
 
     vector<unsigned char> rsaModulus(bufSize, 0);
-    if(BN_bn2bin(rsa->n, rsaModulus.data()) <= 0)
+    if(BN_bn2bin(n, rsaModulus.data()) <= 0)
         return vector<unsigned char>();
 
     return rsaModulus;
@@ -176,7 +195,7 @@
         THROW("Certificate does not have a public key, can not verify signature.");
 
     int result = 0;
-    switch(EVP_PKEY_type(key->type))
+    switch(EVP_PKEY_base_id(key.get()))
     {
     case EVP_PKEY_RSA:
     {
@@ -190,10 +209,9 @@
     {
         SCOPE(EC_KEY, ec, EVP_PKEY_get1_EC_KEY(key.get()));
         SCOPE(ECDSA_SIG, sig, ECDSA_SIG_new());
-        BN_free(sig->r);
-        BN_free(sig->s);
-        sig->r = BN_bin2bn(signature.data(), int(signature.size()/2), 0);
-        sig->s = BN_bin2bn(&signature[signature.size()/2], int(signature.size()/2), 0);
+        ECDSA_SIG_set0(sig.get(),
+            BN_bin2bn(signature.data(), int(signature.size()/2), 0),
+            BN_bin2bn(&signature[signature.size()/2], int(signature.size()/2), 0));
         result = ECDSA_do_verify(digest.data(), (unsigned int)digest.size(), sig.get(), ec.get());
         //result = ECDSA_verify(Digest::toMethod(method), digest.data(), (unsigned int)digest.size(),
         //    const_cast<unsigned char*>(signature.data()), (unsigned int)signature.size(), ec.get());