Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Manuel Wagesreither
Dear all,

I'm struggling with programatically verifying a certificate which is solely stored in memory, i. e. not on the file system. The certificate and the CA seem to be fine though, because when I extract them from memory and store them as a file, and use the `openssl verify`, verification is successful. Hence I suspect my code is faulty.

Unfortunately, I'm under the impression that validating certificates which exist solely in memory is a niche application. I was yet not able to find a comprehensive tutorial or even a code sample on the internet. Hence, I hope you can help me.

Below I'm posting my sample code. (I have stripped the certificate and CA raw data, tough.) It can be compiled an run under a GNU/Linux system.
When this code is run, OpenSSL emits a "certificate signature failure" with an error depth of 0.

Thanks a lot!
Manuel

============

#include <openssl/x509.h>
#include <stdexcept>
#include <iostream>

unsigned char g_authority[] = { 0x30, 0x82, 0x03, 0x00 /* and so on */ };
unsigned char g_cert[] = { 0x30, 0x82, 0x02, 0x9b /* and so on */ };

int main(int, char**)
{
        // This holds the return codes and gets reused for most function calls
        int rc = 0;

        // Make a new store
        X509_STORE *x509_store = X509_STORE_new();
        if (x509_store == NULL) {
                throw std::runtime_error("X509_STORE_new() failed");
        }

        // Load and convert the authoritys certificate to a compatible form
        X509 *auth_cert = NULL;
        {
                const unsigned char* auth_cert_ptr = g_authority;
                auth_cert = d2i_X509(NULL, &auth_cert_ptr, sizeof(g_authority));
                if (auth_cert == nullptr) {
                        throw std::runtime_error("d2i_X509() failed for authoritys certificate");
                }
        }

        // Add the authoritys certificate to the store
        rc = X509_STORE_add_cert(x509_store, auth_cert);
        if (rc != 1) {
                throw std::runtime_error("X509_STORE_add_cert() failed");
        }

        // Make a new store context
        X509_STORE_CTX *x509_store_ctx = X509_STORE_CTX_new();
        if (x509_store_ctx == NULL) {
                throw std::runtime_error("X509_STORE_CTX_new() failed");
        }

        // Load and convert the certificate to be verified to a compatible form
        X509 *myself = NULL;
        {
                const unsigned char *my_cert_ptr = g_cert;
                myself = d2i_X509(NULL, &my_cert_ptr, sizeof(g_cert));
                if (myself == NULL) {
                        throw std::runtime_error("d2i_X509() failed for own certificate");
                }
        }

        rc = X509_STORE_CTX_init(x509_store_ctx, x509_store, myself, NULL);
        if (rc != 1) {
                throw std::runtime_error("X509_STORE_CTX_init() failed");
        }

        rc = X509_verify_cert(x509_store_ctx);

        X509_STORE_free(x509_store);
        X509_STORE_CTX_free(x509_store_ctx);

        if (rc > 0) {
                std::cout << X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_store_ctx)) << std::endl;
                return 0;
        } else {
                std::cerr << X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_store_ctx)) << std::endl;
                std::cerr << "Error depth: " << X509_STORE_CTX_get_error_depth(x509_store_ctx) << std::endl;
                return 1;
        }
}
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Manuel Wagesreither
Dear all,

I forgot to mention that I'm using OpenSSL 1.0.2k.

Regards
Manuel
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Sands, Daniel
In reply to this post by Manuel Wagesreither
I'm a fellow SSL-USER and not an expert, but my verification flow goes
as follows:

X509_STORE_CTX_new()
X509_STORE_CTX_init(ctx,NULL,cert,NULL) <-- The certificate to verify
X509_STORE_CTX_trusted_stack(ctx,CACertificateStack) <-- Perhaps this
is the difference?
X509_verify_cert(ctx)


On Thu, 2017-12-21 at 12:42 +0100, Manuel Wagesreither wrote:

> Dear all,
>
> I'm struggling with programatically verifying a certificate which is
> solely stored in memory, i. e. not on the file system. The
> certificate and the CA seem to be fine though, because when I extract
> them from memory and store them as a file, and use the `openssl
> verify`, verification is successful. Hence I suspect my code is
> faulty.
>
> Unfortunately, I'm under the impression that validating certificates
> which exist solely in memory is a niche application. I was yet not
> able to find a comprehensive tutorial or even a code sample on the
> internet. Hence, I hope you can help me.
>
> Below I'm posting my sample code. (I have stripped the certificate
> and CA raw data, tough.) It can be compiled an run under a GNU/Linux
> system.
> When this code is run, OpenSSL emits a "certificate signature
> failure" with an error depth of 0.
>
> Thanks a lot!
> Manuel
>
> ============
>
> #include <openssl/x509.h>
> #include <stdexcept>
> #include <iostream>
>
> unsigned char g_authority[] = { 0x30, 0x82, 0x03, 0x00 /* and
> so on */ };
> unsigned char g_cert[] = { 0x30, 0x82, 0x02, 0x9b /* and so on */ };
>
> int main(int, char**)
> {
> // This holds the return codes and gets reused for most
> function calls
> int rc = 0;
>
> // Make a new store
> X509_STORE *x509_store = X509_STORE_new();
> if (x509_store == NULL) {
> throw std::runtime_error("X509_STORE_new() failed");
> }
>
> // Load and convert the authoritys certificate to a compatible
> form
> X509 *auth_cert = NULL;
> {
> const unsigned char* auth_cert_ptr = g_authority;
> auth_cert = d2i_X509(NULL, &auth_cert_ptr,
> sizeof(g_authority));
> if (auth_cert == nullptr) {
> throw std::runtime_error("d2i_X509() failed for
> authoritys certificate");
> }
> }
>
> // Add the authoritys certificate to the store
> rc = X509_STORE_add_cert(x509_store, auth_cert);
> if (rc != 1) {
> throw std::runtime_error("X509_STORE_add_cert()
> failed");
> }
>
> // Make a new store context
> X509_STORE_CTX *x509_store_ctx = X509_STORE_CTX_new();
> if (x509_store_ctx == NULL) {
> throw std::runtime_error("X509_STORE_CTX_new()
> failed");
> }
>
> // Load and convert the certificate to be verified to a
> compatible form
> X509 *myself = NULL;
> {
> const unsigned char *my_cert_ptr = g_cert;
> myself = d2i_X509(NULL, &my_cert_ptr, sizeof(g_cert));
> if (myself == NULL) {
> throw std::runtime_error("d2i_X509() failed for
> own certificate");
> }
> }
>
> rc = X509_STORE_CTX_init(x509_store_ctx, x509_store, myself,
> NULL);
> if (rc != 1) {
> throw std::runtime_error("X509_STORE_CTX_init()
> failed");
> }
>
> rc = X509_verify_cert(x509_store_ctx);
>
> X509_STORE_free(x509_store);
> X509_STORE_CTX_free(x509_store_ctx);
>
> if (rc > 0) {
> std::cout <<
> X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_store_ctx
> )) << std::endl;
> return 0;
> } else {
> std::cerr <<
> X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_store_ctx
> )) << std::endl;
> std::cerr << "Error depth: " <<
> X509_STORE_CTX_get_error_depth(x509_store_ctx) << std::endl;
> return 1;
> }
> }
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Manuel Wagesreither
Unfortunately this didn't work either. The end result is the same; OpenSSL still emits a "certificate signature failure" with an error depth of 0.

Regards,
Manuel


Am Do, 21. Dez 2017, um 19:27, schrieb Sands, Daniel:

> I'm a fellow SSL-USER and not an expert, but my verification flow goes
> as follows:
>
> X509_STORE_CTX_new()
> X509_STORE_CTX_init(ctx,NULL,cert,NULL) <-- The certificate to verify
> X509_STORE_CTX_trusted_stack(ctx,CACertificateStack) <-- Perhaps this
> is the difference?
> X509_verify_cert(ctx)
>
>
> On Thu, 2017-12-21 at 12:42 +0100, Manuel Wagesreither wrote:
> > Dear all,
> >
> > I'm struggling with programatically verifying a certificate which is
> > solely stored in memory, i. e. not on the file system. The
> > certificate and the CA seem to be fine though, because when I extract
> > them from memory and store them as a file, and use the `openssl
> > verify`, verification is successful. Hence I suspect my code is
> > faulty.
> >
> > Unfortunately, I'm under the impression that validating certificates
> > which exist solely in memory is a niche application. I was yet not
> > able to find a comprehensive tutorial or even a code sample on the
> > internet. Hence, I hope you can help me.
> >
> > Below I'm posting my sample code. (I have stripped the certificate
> > and CA raw data, tough.) It can be compiled an run under a GNU/Linux
> > system.
> > When this code is run, OpenSSL emits a "certificate signature
> > failure" with an error depth of 0.
> >
> > Thanks a lot!
> > Manuel
> >
> > ============
> >
> > #include <openssl/x509.h>
> > #include <stdexcept>
> > #include <iostream>
> >
> > unsigned char g_authority[] = { 0x30, 0x82, 0x03, 0x00 /* and
> > so on */ };
> > unsigned char g_cert[] = { 0x30, 0x82, 0x02, 0x9b /* and so on */ };
> >
> > int main(int, char**)
> > {
> > // This holds the return codes and gets reused for most
> > function calls
> > int rc = 0;
> >
> > // Make a new store
> > X509_STORE *x509_store = X509_STORE_new();
> > if (x509_store == NULL) {
> > throw std::runtime_error("X509_STORE_new() failed");
> > }
> >
> > // Load and convert the authoritys certificate to a compatible
> > form
> > X509 *auth_cert = NULL;
> > {
> > const unsigned char* auth_cert_ptr = g_authority;
> > auth_cert = d2i_X509(NULL, &auth_cert_ptr,
> > sizeof(g_authority));
> > if (auth_cert == nullptr) {
> > throw std::runtime_error("d2i_X509() failed for
> > authoritys certificate");
> > }
> > }
> >
> > // Add the authoritys certificate to the store
> > rc = X509_STORE_add_cert(x509_store, auth_cert);
> > if (rc != 1) {
> > throw std::runtime_error("X509_STORE_add_cert()
> > failed");
> > }
> >
> > // Make a new store context
> > X509_STORE_CTX *x509_store_ctx = X509_STORE_CTX_new();
> > if (x509_store_ctx == NULL) {
> > throw std::runtime_error("X509_STORE_CTX_new()
> > failed");
> > }
> >
> > // Load and convert the certificate to be verified to a
> > compatible form
> > X509 *myself = NULL;
> > {
> > const unsigned char *my_cert_ptr = g_cert;
> > myself = d2i_X509(NULL, &my_cert_ptr, sizeof(g_cert));
> > if (myself == NULL) {
> > throw std::runtime_error("d2i_X509() failed for
> > own certificate");
> > }
> > }
> >
> > rc = X509_STORE_CTX_init(x509_store_ctx, x509_store, myself,
> > NULL);
> > if (rc != 1) {
> > throw std::runtime_error("X509_STORE_CTX_init()
> > failed");
> > }
> >
> > rc = X509_verify_cert(x509_store_ctx);
> >
> > X509_STORE_free(x509_store);
> > X509_STORE_CTX_free(x509_store_ctx);
> >
> > if (rc > 0) {
> > std::cout <<
> > X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_store_ctx
> > )) << std::endl;
> > return 0;
> > } else {
> > std::cerr <<
> > X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_store_ctx
> > )) << std::endl;
> > std::cerr << "Error depth: " <<
> > X509_STORE_CTX_get_error_depth(x509_store_ctx) << std::endl;
> > return 1;
> > }
> > }
> --
> openssl-users mailing list
> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Jan Just Keijser-2
Hi,

On 22/12/17 11:14, Manuel Wagesreither wrote:
> Unfortunately this didn't work either. The end result is the same; OpenSSL still emits a "certificate signature failure" with an error depth of 0.
>
>
here's a stripped down version of my 'grid-proxy-verify.c' that verifies
a certificate loaded from memory. My cert is included in the file. The
CA used to verify the certificate is loaded from a directory, but the
principle for reading a CA file from memory is the same:

char CAdata[] = "....";

if ( !(CA_bio = BIO_new_mem_buf(CAdata, -1) ) ) return ERR_get_error();

etc.
This code is a bit overkill - it will verify a stack of certificates,
not just a single one, but I am sure you can rework it just to verify a
single cert ;)


HTH,

JJK

====

#define _GNU_SOURCE

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>

#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/x509_vfy.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/pem.h>

#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/des.h>
#include <openssl/rand.h>

#include <openssl/buffer.h>
#include <openssl/objects.h>

#define L_ERROR  0  /* errors */
#define L_WARN   1  /* all unusual */
#define L_INFO   2  /* all status changes etc. */
#define L_DEBUG  3  /* all, including trace */

int    log_level = 1;

void Log( int msg_level, const char *msg, ...)
{
     va_list argp;

     if ( log_level >= msg_level )
     {
         if (msg_level == L_WARN )  fprintf( stderr, "Warning: " );
         if (msg_level == L_INFO )  fprintf( stderr, "Info:    " );
         if (msg_level == L_DEBUG ) fprintf( stderr, "Debug:   " );
         va_start( argp, msg );
         vfprintf( stderr, msg, argp );
         va_end( argp );
         fprintf( stderr, "\n" );
     }
}

void Error( const char *operation, const char *msg, ...)
{
     va_list argp;

     fprintf( stderr, "ERROR:  %s: ", operation );
     va_start( argp, msg );
     vfprintf( stderr, msg, argp );
     va_end( argp );
     fprintf( stderr, "\n" );
}


unsigned long read_memCert( STACK_OF(X509) **certstack )
{
     char                *oper = "Reading mem";

     STACK_OF(X509_INFO) *sk      = NULL;
     BIO                 *certbio = NULL;
     X509_INFO           *xi;
     unsigned long        err;

     char data[] = "\n\
-----BEGIN CERTIFICATE-----\n\
MIIE7zCCA9egAwIBAgICFF8wDQYJKoZIhvcNAQELBQAwUjELMAkGA1UEBhMCTkwx\n\
DzANBgNVBAoTBk5JS0hFRjEyMDAGA1UEAxMpTklLSEVGIG1lZGl1bS1zZWN1cml0\n\
eSBjZXJ0aWZpY2F0aW9uIGF1dGgwHhcNMTcwNTMxMDAwMDAwWhcNMTgwNTMxMTQ1\n\
NzQwWjBQMRIwEAYDVQQKEwlkdXRjaGdyaWQxDjAMBgNVBAoTBXVzZXJzMQ8wDQYD\n\
VQQKEwZuaWtoZWYxGTAXBgNVBAMTEEphbiBKdXN0IEtlaWpzZXIwggEiMA0GCSqG\n\
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCUgM6fRU95Qs/qiquRpLqtLFX2EEooIFFm\n\
Jo0IxwpISgIq37HUgfbNBB97ZXaMDtrWrcJt1PbXIj7NCXsDJ4V6zueKwx3Dsr2W\n\
H5V9FvK6bj+vz3S1bOvG1EJUpnS81/Fmlawkd7bK7dXwuZVbUp7QcmzGuwmFO3/3\n\
h2sX5a1z7gkb3VZXIyFk2lz1W+bt4bgb6WNvcOZuXwbawsF4F6LZkaHJ6JwsuZMc\n\
/gIOhQYXD4+KPOG96/PRgpC7BBWcwfmg9fPNxp09QD6q9XEM9MN307BYQ7BWAgrq\n\
yUvhL69/+DIBCwkcUnzWxeZbcsfziHx/HUR251NybNsp6Mu+IdjJAgMBAAGjggHP\n\
MIIByzAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIEsDAdBgNVHSUEFjAUBggr\n\
BgEFBQcDAgYIKwYBBQUHAwQwOAYDVR0fBDEwLzAtoCugKYYnaHR0cDovL2NhLmR1\n\
dGNoZ3JpZC5ubC9tZWRpdW0vY2FjcmwuZGVyMCgGA1UdIAQhMB8wDwYNKwYBBAHR\n\
QgQCAgEDAjAMBgoqhkiG90wFAgIBMB8GA1UdIwQYMBaAFFsFOpnG1SK9/ZSA/BGo\n\
0PFx1kukMB0GA1UdDgQWBBRrObKYCp8RcKwXn4kcHa6zFXpU7DARBglghkgBhvhC\n\
AQEEBAMCBaAwNAYJYIZIAYb4QgEIBCcWJWh0dHA6Ly9jYS5kdXRjaGdyaWQubmwv\n\
bWVkaXVtL3BvbGljeS8wgZ4GCWCGSAGG+EIBDQSBkBaBjUVFQyBpc3N1ZWQgdW5k\n\
ZXIgcG9saWN5IHZlcnNpb24gMy4yIC0gbGltaXRlZCBsaWFiaWxpdGllcyBhcHBs\n\
eSwgc2VlIGh0dHA6Ly9jYS5kdXRjaGdyaWQubmwvbWVkaXVtL3BvbGljeS8gLSBD\n\
ZXJ0aWZpY2F0ZSBUYWc6IDY5MDRhMTdkLTk0ODBjZTANBgkqhkiG9w0BAQsFAAOC\n\
AQEAeLFnQAYF4FWHJ0y+7T9bUtFoQLv6ZsqBlaSwlzuhpSMlOVvzOLvqlmLVdbk5\n\
nkEBu008FBTA2r9UysIhB00MxhypAxkhzIXxfslZBwtxdmZ0s0MBoIwLb6Lo3Td5\n\
ktFKra31KOlwdiAFZxmsi5Du4p+sY5uW5RNIsa9dxqccOd0+TOglARF/sF5xliHv\n\
x8y+qvVmiMBa0nZmvqO0OQfTb4oNbByGeeH6yQyQqxWpJwwdXx+Q4JJhZhXAJIOt\n\
Ze52sXps/K/1R3laqXaEW7xYZbragtgimbkMkPCHr6624ajslViyqI2efwlI1+em\n\
ueVU4EK03fp65Egd6Qs9yx5+VA==\n\
-----END CERTIFICATE-----\n\
";

     Log( L_DEBUG, "--- Welcome to the read_memCert function ---");

     *certstack = sk_X509_new_null();
     if (*certstack == NULL) return ERR_get_error();

     if ( !(certbio = BIO_new_mem_buf(data, -1) ) ) return ERR_get_error();

     Log( L_DEBUG, "Reading X509_INFO records" );
     if ( !(sk=PEM_X509_INFO_read_bio(certbio, NULL, NULL, NULL)) )
     {
         err = ERR_get_error();
         Error( oper, "No X509 records found" );
         BIO_free(certbio);
         sk_X509_INFO_free(sk);
         sk_X509_free(*certstack);
         *certstack = NULL;
         return err;
     }

     while (sk_X509_INFO_num(sk))
     {
         xi=sk_X509_INFO_shift(sk);
         if (xi->x509 != NULL)
         {
             sk_X509_push(*certstack, xi->x509);
             xi->x509=NULL;
         }
         X509_INFO_free(xi);
     }

     if (!sk_X509_num(*certstack))
     {
         err = ERR_get_error();
         Error( oper, "No certificates found" );
         BIO_free(certbio);
         sk_X509_INFO_free(sk);
         sk_X509_free(*certstack);
         *certstack = NULL;
         return err;
     }

     BIO_free(certbio);
     sk_X509_INFO_free(sk);

     return X509_V_OK;
}

static int mem_verify_callback(int ok, X509_STORE_CTX *ctx)
{
     unsigned long   errnum   = X509_STORE_CTX_get_error(ctx);
     int             errdepth = X509_STORE_CTX_get_error_depth(ctx);
     STACK_OF(X509) *certstack;
     X509           *cert = NULL;
     char           *cert_DN = NULL;

     Log( L_DEBUG, "--- Welcome to the mem_verify_callback function ---");

     cert    = X509_STORE_CTX_get_current_cert(ctx);
     cert_DN = X509_NAME_oneline( X509_get_subject_name( cert), NULL, 0);
     Log( L_DEBUG, "cert DN: %s", cert_DN );

     if (ok != 1)
     {
         Log( L_INFO, "mem_verify_callback: error message=%s",
                      X509_verify_cert_error_string (errnum));
     }

     free(cert_DN);

     return ok;
}


unsigned long mem_verifyCert( char * CA_DIR, STACK_OF(X509) *certstack )
{
     char           *oper = "Verifying certificate chain";

     X509_STORE     *store      = NULL;
     X509_LOOKUP    *lookup     = NULL;
     X509_STORE_CTX *verify_ctx = NULL;
     X509           *cert       = NULL;
     char           *cert_DN;
     char           *issuer_DN;
     int             i = 0;
     int             depth      = sk_X509_num( certstack );
     unsigned long   ret        = X509_V_OK;

     Log( L_DEBUG, "--- Welcome to the mem_verifyCert function ---");

     /* Initials must be good */
     if ( CA_DIR == NULL )
     {
         Error( oper, "No CA certificate directory specified." );
         return X509_V_ERR_APPLICATION_VERIFICATION;
     }
     if ( certstack == NULL )
     {
         Error( oper, "Certificate stack is empty." );
         return X509_V_ERR_APPLICATION_VERIFICATION;
     }

     Log( L_INFO, "Using CA Directory: %s", CA_DIR);

     Log( L_DEBUG, "X509_STORE_new");
     if (!(store = X509_STORE_new()))
     {
        Error( oper, "Could not create a X509 STORE." );
        return ERR_get_error();
     }

     Log( L_DEBUG, "X509_STORE_set_verify_cb_func");
     X509_STORE_set_verify_cb_func (store, mem_verify_callback);

     /* Executing the lookups to the CA and CRL files */
     Log( L_DEBUG, "X509_STORE_load_locations");
     if (X509_STORE_load_locations (store, NULL, CA_DIR) != 1)
     {
         Error( oper, "Could not load the CA directory.");
         return ERR_get_error();
     }

     Log( L_DEBUG, "X509_STORE_set_default_paths");
     if (X509_STORE_set_default_paths(store) != 1)
     {
         Error( oper, "Could not load the system wide CA certificates.");
         return ERR_get_error();
     }

     Log( L_DEBUG, "X509_STORE_add_lookup");
     if (!(lookup = X509_STORE_add_lookup (store, X509_LOOKUP_hash_dir())))
     {
         Error( oper, "Could not create X509_LOOKUP object.");
         return ERR_get_error();
     }

     Log( L_DEBUG, "X509_LOOKUP_add_dir");
     i=X509_LOOKUP_add_dir (lookup, CA_DIR, X509_FILETYPE_PEM);
     if (!i)
     {
         Error( oper, "Coult not add CA_DIR.");
         return ERR_get_error();
     }

     Log( L_DEBUG, "X509_STORE_CTX_new");
     /* Creating a verification context and initialize it */
     if (!(verify_ctx = X509_STORE_CTX_new()))
     {
         Error( oper, "Could not create a X509 STORE CTX (context).");
         return ERR_get_error();
     }

     for (i=depth-1; i >= 0; --i)
     {
         if ((cert = sk_X509_value(certstack, i)))
         {
             cert_DN   =
X509_NAME_oneline(X509_get_subject_name(cert),NULL,0);
             issuer_DN =
X509_NAME_oneline(X509_get_issuer_name(cert),NULL,0);

             Log( L_DEBUG, "DN[%d]:        %s", i, cert_DN );
             Log( L_DEBUG, "Issuer DN[%d]: %s", i, issuer_DN);

             free( cert_DN );
             free( issuer_DN );

         }
     }

     cert = sk_X509_value( certstack, 0 );
     cert_DN   = X509_NAME_oneline( X509_get_subject_name( cert ) ,
NULL, 0 );
     issuer_DN = X509_NAME_oneline( X509_get_issuer_name( cert )  ,
NULL, 0 );

     Log( L_INFO, "Certificate to verify:" );
     Log( L_INFO, "  DN:        %s", cert_DN );
     Log( L_INFO, "  Issuer DN: %s", issuer_DN );

     free( cert_DN );
     free( issuer_DN );

     Log( L_DEBUG, "X509_STORE_CTX_init" );
     if ( X509_STORE_CTX_init( verify_ctx, store, cert, certstack ) != 1 )
     {
         Error( oper, "Could not initialize verification context.");
         return ERR_get_error();
     }

     X509_STORE_CTX_set_purpose( verify_ctx, X509_PURPOSE_SSL_CLIENT );

     Log( L_DEBUG, "X509_verify");
     if ( (X509_verify_cert( verify_ctx ) ) != 1 )
     {
         ret = verify_ctx->error;
     }
     else
     {
         Log( L_INFO, "The verification of the certicate has succeeded.");
     }

     if ( verify_ctx ) X509_STORE_CTX_free( verify_ctx );
     if ( store )      X509_STORE_free( store );

     return ret;
}


int main( int argc, char **argv )
{
     char             *CA_dir = NULL;

     unsigned long     i, result = 0;
     char             *long_opt;
     struct stat       my_stat;
     STACK_OF(X509)   *certStack = NULL;

     OpenSSL_add_all_algorithms();
     ERR_load_crypto_strings();

     for (i = 1; i < argc; i++)
     {
         if ( (strlen(argv[i]) >= 2 ) && ( argv[i][0] == '-' ) )
         {
             switch (argv[i][1])
             {
                 case '-': long_opt = argv[i]+2;
                           if ( strcmp( long_opt, "debug") == 0 )
                               log_level++;
                           else if ( strcmp( long_opt, "quiet") == 0 )
                               log_level = 0;
                           else
                               fprintf( stderr, "Unknown option: %s\n",
argv[i] );
                           break;
                 case 'd': log_level++;
                           break;
                 case 'q': log_level = 0;
                           break;
                 default:  fprintf( stderr, "Unknown option: %s\n",
argv[i] );
             }
         }
     }

     /* First, find the trusted CA directory */
     CA_dir = getenv( "X509_CERT_DIR" );
     if ( CA_dir == NULL ) CA_dir = "/etc/grid-security/certificates/";

     Log ( L_DEBUG, "Testing CA directory %s", CA_dir );
     if ( (result = stat( CA_dir, &my_stat ) ) != 0 )
     {
         CA_dir = getenv( "HOME" );
         strcat( CA_dir, "/.globus/certificates/" );

         Log ( L_DEBUG, "Testing CA directory %s", CA_dir );
         result = stat( CA_dir, &my_stat );
     }
     if (result != 0 ) Log( L_WARN, "Trusted certificate directory not
found!" );

     result = read_memCert( &certStack );
     if ( result == X509_V_OK )
     {
         result = mem_verifyCert( CA_dir, certStack );
         if ( result == X509_V_OK )
         {
             printf( "OK\n" );
         }
         else
             Error( "Verifying certificate chain", "%s\n",
                    X509_verify_cert_error_string( result ) );
     }
     else
         Error( "Reading memory", "%s\n",
                ERR_reason_error_string( result ) );

     sk_X509_pop_free( certStack, X509_free );

     /* make valgrind happy */
     ERR_remove_state(0);
     ERR_free_strings();
     EVP_cleanup();
     CRYPTO_cleanup_all_ex_data();

     return ( !( result == X509_V_OK ) );
}


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Manuel Wagesreither
In reply to this post by Manuel Wagesreither
Dear all,

I just found out that this problem only occurs when I'm linking the executable against libssl 1.0.1k. When linking against libssl 1.1.0f, the certificate does get validated fine.

Does anyone know possible reasons? Do these libssl versions differ in regard to certificate validation? I would like my code to work with libssl 1.0.1k preferably.

Regards,
Manuel
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Certificate gets verified OK over SSL-CLI, but not when using SSL-API

OpenSSL - User mailing list
Yes, the certificate validation was fixed, and improved, in 1.1.0.

You should not use 1.0.1 if you can at all avoid it.  It has many bugs, probably security issues, and missing features.  Like, for example, cert validation.
 

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Sands, Daniel
In reply to this post by Manuel Wagesreither
On Fri, 2017-12-22 at 11:14 +0100, Manuel Wagesreither wrote:
> Unfortunately this didn't work either. The end result is the same;
> OpenSSL still emits a "certificate signature failure" with an error
> depth of 0.
>
In light of what Salz said about verification, could we assume that the
openssl verify program that succeeded is based on the older library?

It could be that your CA cert is missing an extension that OSSL now
checks for, such as (spitballing here) that the certificate is valid
for certificate signing.

You could check by substituting other certificates in your program to
see if the code itself works, and also closely examine your own
certificates to make sure all the requirements are met.
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Viktor Dukhovni
In reply to this post by Manuel Wagesreither


> On Dec 21, 2017, at 6:42 AM, Manuel Wagesreither <[hidden email]> wrote:
>
>
> #include <openssl/x509.h>
> #include <stdexcept>
> #include <iostream>
>
> unsigned char g_authority[] = { 0x30, 0x82, 0x03, 0x00 /* and so on */ };
> unsigned char g_cert[] = { 0x30, 0x82, 0x02, 0x9b /* and so on */ };

Eliding the certificate data makes it very difficult to provide
meaningful feedback.

>
> int main(int, char**)
> {
> // This holds the return codes and gets reused for most function calls
> int rc = 0;
>
> // Make a new store
> X509_STORE *x509_store = X509_STORE_new();
> if (x509_store == NULL) {
> throw std::runtime_error("X509_STORE_new() failed");
> }
>
> // Load and convert the authoritys certificate to a compatible form
> X509 *auth_cert = NULL;
> {
> const unsigned char* auth_cert_ptr = g_authority;
> auth_cert = d2i_X509(NULL, &auth_cert_ptr, sizeof(g_authority));
> if (auth_cert == nullptr) {
> throw std::runtime_error("d2i_X509() failed for authoritys certificate");
> }
> }
>
> // Add the authoritys certificate to the store
> rc = X509_STORE_add_cert(x509_store, auth_cert);
> if (rc != 1) {
> throw std::runtime_error("X509_STORE_add_cert() failed");
> }
>
> // Make a new store context
> X509_STORE_CTX *x509_store_ctx = X509_STORE_CTX_new();
> if (x509_store_ctx == NULL) {
> throw std::runtime_error("X509_STORE_CTX_new() failed");
> }
>
> // Load and convert the certificate to be verified to a compatible form
> X509 *myself = NULL;
> {
> const unsigned char *my_cert_ptr = g_cert;
> myself = d2i_X509(NULL, &my_cert_ptr, sizeof(g_cert));
> if (myself == NULL) {
> throw std::runtime_error("d2i_X509() failed for own certificate");
> }
> }
>
> rc = X509_STORE_CTX_init(x509_store_ctx, x509_store, myself, NULL);
> if (rc != 1) {
> throw std::runtime_error("X509_STORE_CTX_init() failed");
> }
>
> rc = X509_verify_cert(x509_store_ctx);
>
> X509_STORE_free(x509_store);
> X509_STORE_CTX_free(x509_store_ctx);

You're freeing x509_store_ctx too early, it is used below for error
reporting.

>
> if (rc > 0) {
> std::cout << X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_store_ctx)) << std::endl;
> return 0;
> } else {
> std::cerr << X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_store_ctx)) << std::endl;
> std::cerr << "Error depth: " << X509_STORE_CTX_get_error_depth(x509_store_ctx) << std::endl;
> return 1;
> }
> }

Please re-post the source code with the *complete* certificate
data.

--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Manuel Wagesreither
Thanks for your feedback. Unfortunately I cannot include the certificate raw data as it may contain sensitive information. Also, I'm unable to replace them with self-made certificates as I don't know the parameters the original ones were created with in the first place. The original creators are inaccessible at the moment. If the problem persists, I will reproduce the problem with test certificates (whose raw data I can publish) in a few weeks.
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Manuel Wagesreither
In reply to this post by Sands, Daniel
Am Fr, 22. Dez 2017, um 20:31, schrieb Sands, Daniel:
> On Fri, 2017-12-22 at 11:14 +0100, Manuel Wagesreither wrote:
> > Unfortunately this didn't work either. The end result is the same;
> > OpenSSL still emits a "certificate signature failure" with an error
> > depth of 0.
> >
> In light of what Salz said about verification, could we assume that the
> openssl verify program that succeeded is based on the older library?

Thanks for your feedback! Actually it's the other way round. Validation succeeds with the *new* library (libssl.so.1.1), and fails with the *old* one (libssl.so.1.0.0). This is true with the openssl verify program as well: `openssl verify` succeeds for OpenSSL 1.1.0f, and fails for OpenSSL 1.0.1g.

Hence, if at all, verification requirements must have been lowered in the new OpenSSL version. I'm just about to look for a list of criterias a certificate has to pass in order to validate successfully in the two OpenSSL versions.
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Viktor Dukhovni
In reply to this post by Manuel Wagesreither


> On Dec 28, 2017, at 4:54 AM, Manuel Wagesreither <[hidden email]> wrote:
>
> Thanks for your feedback. Unfortunately I cannot include the certificate raw data as it may contain sensitive information. Also, I'm unable to replace them with self-made certificates as I don't know the parameters the original ones were created with in the first place. The original creators are inaccessible at the moment. If the problem persists, I will reproduce the problem with test certificates (whose raw data I can publish) in a few weeks.

You should be able to publish edited output of:

    openssl crl2pkcs7 -nocrl -certfile chain.pem |
        openssl pkcs7 -print_certs -text -noout

With any sensitive values hand-replaced with "censored-NNN"
where the "NNN" part uniquely corresponds to each original
value (same values get same "NNN", distinct values get
distinct "NNN").

The "chain.pem" file should have the leaf certificate first,
then its issuer, then the issuer of that certificate, ...
up to the trust anchor.  Please also make sure that the
chain in question passes (with OpenSSL 1.1.0 per your report)
is reported verified with:

    $ openssl verify -no-CApath -no-CAfile \
        -trusted root.pem -untrusted chain.pem \
        chain.pem

Where "root.pem" contains just the last certificate
from the chain.pem file.  Post the output of that
command for 1.1.0.  Please also report similar output
for 1.0.2, with the command modified to:

    $ capath=$(mktemp -d empty.XXXXXX)
    $ cafile=root.pem
    $ openssl verify -CApath $capath -CAfile root.pem \
        -trusted root.pem -untrusted chain.pem \
        chain.pem

Again, if anything in the output is sensitive, censor the
values, with "censoredNNN" matching the replacements in
the certificate chain.

--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Certificate gets verified OK over SSL-CLI, but not when using SSL-API

OpenSSL - User mailing list
In reply to this post by Manuel Wagesreither
> Hence, if at all, verification requirements must have been lowered in the new OpenSSL version.

No, it is also the case that the new version now more correctly accepts some chains as valid that because of bugs, the old version did not.


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Manuel Wagesreither
> > Hence, if at all, verification requirements must have been lowered in the new OpenSSL version.
>
> No, it is also the case that the new version now more correctly accepts
> some chains as valid that because of bugs, the old version did not.

Understood! My reply was related to message only, as I was afraid he might have mistook the problem description. Hence, I wanted to clarify this.

I have taken your advice to upgrade to OpenSSL 1.1.0 seriously and did accordingly. We are now using OpenSSL 1.1.0g and everything seems to be doing fine so far. This matter can thus be regarded as solved.

Thanks to everyone who contributed!

Best regards,
Manuel
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Certificate gets verified OK over SSL-CLI, but not when using SSL-API

Manuel Wagesreither
In reply to this post by Viktor Dukhovni
Dear Viktor,

that's quite an detailed elaboration. I have learned something from what you posted, but as far as this problem is concerned, we we're able to get rid of your problems by upgrading to OpenSSL 1.1.0g. I'm sure what you conveyed will be of help when diagnosing future OpenSSL problems, which, I have no doubt, will arise sooner or later.

Thank you for your help!
Manuel
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users