1 (edited by zhq0918 2019-05-23 04:52:23)

Topic: how can i load the certificate chain in client?

I want verify the certificate chain in sgx., and i load the certificate chain by function which named SSL_CTX_use_certificate_chain_file,as flows:
SSL_CTX *ctx = SSL_CTX_new(TLSv1_2_client_method());
    assert(ctx != NULL);

    if (SSL_CTX_load_verify_locations(ctx, CA_FILE, 0) != 1) {
        SSL_CTX_free(ctx);
        printf("Failed to load CA file %s", CA_FILE);
    }

    if (SSL_CTX_set_default_verify_paths(ctx) != 1) {
        SSL_CTX_free(ctx);
        printf("Call to SSL_CTX_set_default_verify_paths failed");
    }

    if (SSL_CTX_use_certificate_file(ctx, CLIENT_CERT, SSL_FILETYPE_PEM) != 1) {
        SSL_CTX_free(ctx);
        printf("Failed to load client certificate from %s", CLIENT_KEY);
    }   
   
    if (SSL_CTX_use_PrivateKey_file(ctx, CLIENT_KEY, SSL_FILETYPE_PEM) != 1) {
        SSL_CTX_free(ctx);
        printf("Failed to load client private key from %s", CLIENT_KEY);
    }

    if (SSL_CTX_check_private_key(ctx) != 1) {
         SSL_CTX_free(ctx);
         printf("SSL_CTX_check_private_key failed");
    }
    printf("%d\n",__LINE__);
   //load certificate chain
   if (SSL_CTX_use_certificate_chain_file(ctx,CA_CHAIN_FILE) != 1){
        SSL_CTX_free(ctx);
        printf("Failed to load client certificate from %s", CA_CHAIN_FILE);
    }
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, &verify_callback);

In server, I checked the certificate in callback function. as flows:

int verifyCallback(int preverify, WOLFSSL_X509_STORE_CTX* store){
    (void) preverify; // unused
    int ret = wolfSSL_X509_verify_cert(store);//This function verifies certificate chain in ctx.
    if (ret == WOLFSSL_FATAL_ERROR){
        printf("Verifies certificate chain in ctx failed!!\n");
    }
    else{
        printf("Verifies certificate chain in ctx success!!\n");
    }
    return WOLFSSL_SUCCESS;
}

And i verified the certificate chain with openssl success. but in sgx, the return value of  wolfSSL_X509_verify_cert always is WOLFSSL_FATAL_ERROR,I want know the method of use certificate chain.thanks a lot.

Share

Re: how can i load the certificate chain in client?

And i verified the certificate chain with openssl success. but in sgx, the return value of  wolfSSL_X509_verify_cert always is WOLFSSL_FATAL_ERROR,I want know the method of use certificate chain.thanks a lot.

SSL_CTX_use_certificate_chain_file requires opening a file, reading in from the file stream and closing the file after it's been read into a buffer. On the other issue you were facing problems with the close() function so likely it's erring out unable to open the file stream much less read it in.

I would recommend placing the cert into a buffer and using

wolfSSL_CTX_use_cerificate_buffer(ctx, certBuf, certBufSz, WOLFSSL_FILETYPE_PEM);

instead. Here is an example:

// Header file mycert.h
static const unsigned char certBuf[] = {
"-----BEGIN CERTIFICATE-----\
MIIEyjCCA7KgAwIBAgIJAKrEv0xQvVV3MA0GCSqGSIb3DQEBCwUAMIGeMQswCQYD\
VQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjEVMBMG\
A1UECgwMd29sZlNTTF8yMDQ4MRkwFwYDVQQLDBBQcm9ncmFtbWluZy0yMDQ4MRgw\
FgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29s\
ZnNzbC5jb20wHhcNMTgwNDEzMTUyMzA5WhcNMjEwMTA3MTUyMzA5WjCBnjELMAkG\
A1UEBhMCVVMxEDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xFTAT\
BgNVBAoMDHdvbGZTU0xfMjA0ODEZMBcGA1UECwwQUHJvZ3JhbW1pbmctMjA0ODEY\
MBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdv\
bGZzc2wuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwwPRK/45\
pDJFO1PIhCsqfHSavaoqUgdH1qY2sgcyjtC6aXvGw0Se1IFI/S1oootnu6F1yDYs\
StIb94u6zw357+zxgR57mwNHmr9lzH9lJGmm6BSJW+Q098WwFJP1Z3s6enjhAVZW\
kaYTQo3SPECcTO/Rht83URsMoTv18aNKNeThzpbfG36/TpfQEOioCDCBryALQxTF\
dGe0MoJvjYbCiECZNoO6HkByIhfXUmUkc7DO7xnNrv94bHvAEgPUTnINUG07ozuj\
mV6dyNkMhbPZitlUJttt+qy7/yVMxNF59HHThkAYE7BjtXJOMMSXhIYtVi/XFfd/\
wK71/Fvl+6G60wIDAQABo4IBBzCCAQMwHQYDVR0OBBYEFDPYRWbXaIcYflQNcCeR\
xybXhWXAMIHTBgNVHSMEgcswgciAFDPYRWbXaIcYflQNcCeRxybXhWXAoYGkpIGh\
MIGeMQswCQYDVQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96\
ZW1hbjEVMBMGA1UECgwMd29sZlNTTF8yMDQ4MRkwFwYDVQQLDBBQcm9ncmFtbWlu\
Zy0yMDQ4MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEW\
EGluZm9Ad29sZnNzbC5jb22CCQCqxL9MUL1VdzAMBgNVHRMEBTADAQH/MA0GCSqG\
SIb3DQEBCwUAA4IBAQCAUlRhKneAU0SpgG1F/w0lfRqPI5NTdDUSb/AuIOrtgGNp\
iOYMoUkw4ILbaA9+hKz//3tC+n4vslKf0nleNRInNrzfllhEllXISpQCX0qd3NM6\
922si3lu/L6PI1hqivU4CkL2mHSIUy4Cr+EOvm/MdDN87LTLp0ltgkJP63MpwzIA\
KxX4iHqPbSAbrmVfxdCK0eJkbaOo/mThqVvm0CPWAnJa7AOOh2cZjeSomRXBPZFI\
mY3+rhy/9igbRb6t73KDmvbHO1GjbnpzvYOql/1jtPRrHBSBmu8UJNPhi/QEBIRU\
D2GiqPJQNwwXDLzgwoSF9AuuAMqfJ+JETxULix20\
-----END CERTIFICATE-----"};

// SPECIAL NOTE: Notice the escapes added at the end of each line after copy/paste.
static const int certBufSz = (int) sizeof(certBuf);
// Application code:

#include "mycert.h"

...

    wolfSSL_CTX_use_cerificate_buffer(ctx, certBuf, certBufSz, WOLFSSL_FILETYPE_PEM);

...

Regards,

K

3 (edited by zhq0918 2019-05-28 01:47:38)

Re: how can i load the certificate chain in client?

ok,thank you @Kaleb,I have tested it, and i tried with your cer, but the wolfSSL_CTX_use_certificate_buffer function returned value was -4(WOLFSSL_BAD_FILE). and i tested the wolfSSL_CTX_load_verify_buffer,its returned value was -372(SSL_NO_PEM_HEADER            = -372,   /* no PEM header found */).


And i checked the manual, i found that the function named wolfSSL_X509_verify_cert can verifies certificate chain in ctx ,and i tried tested the function after i loaded the ca chain with function wolfSSL_CTX_use_certificate_chain_buffer_format, but the function returned value was WOLFSSL_FATAL_ERROR,the method i load the ca chain ,is right?if not right ,when and how can i load the ca chain?

Share

Re: how can i load the certificate chain in client?

Try this format instead see if the NO_PEM_HEADER issue persists:

static const unsigned char certBuf[] = {
"-----BEGIN CERTIFICATE-----\n\
MIIEyjCCA7KgAwIBAgIJAKrEv0xQvVV3MA0GCSqGSIb3DQEBCwUAMIGeMQswCQYD\n\
VQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjEVMBMG\n\
A1UECgwMd29sZlNTTF8yMDQ4MRkwFwYDVQQLDBBQcm9ncmFtbWluZy0yMDQ4MRgw\n\
FgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29s\n\
ZnNzbC5jb20wHhcNMTgwNDEzMTUyMzA5WhcNMjEwMTA3MTUyMzA5WjCBnjELMAkG\n\
A1UEBhMCVVMxEDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xFTAT\n\
BgNVBAoMDHdvbGZTU0xfMjA0ODEZMBcGA1UECwwQUHJvZ3JhbW1pbmctMjA0ODEY\n\
MBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdv\n\
bGZzc2wuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwwPRK/45\n\
pDJFO1PIhCsqfHSavaoqUgdH1qY2sgcyjtC6aXvGw0Se1IFI/S1oootnu6F1yDYs\n\
StIb94u6zw357+zxgR57mwNHmr9lzH9lJGmm6BSJW+Q098WwFJP1Z3s6enjhAVZW\n\
kaYTQo3SPECcTO/Rht83URsMoTv18aNKNeThzpbfG36/TpfQEOioCDCBryALQxTF\n\
dGe0MoJvjYbCiECZNoO6HkByIhfXUmUkc7DO7xnNrv94bHvAEgPUTnINUG07ozuj\n\
mV6dyNkMhbPZitlUJttt+qy7/yVMxNF59HHThkAYE7BjtXJOMMSXhIYtVi/XFfd/\n\
wK71/Fvl+6G60wIDAQABo4IBBzCCAQMwHQYDVR0OBBYEFDPYRWbXaIcYflQNcCeR\n\
xybXhWXAMIHTBgNVHSMEgcswgciAFDPYRWbXaIcYflQNcCeRxybXhWXAoYGkpIGh\n\
MIGeMQswCQYDVQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96\n\
ZW1hbjEVMBMGA1UECgwMd29sZlNTTF8yMDQ4MRkwFwYDVQQLDBBQcm9ncmFtbWlu\n\
Zy0yMDQ4MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEW\n\
EGluZm9Ad29sZnNzbC5jb22CCQCqxL9MUL1VdzAMBgNVHRMEBTADAQH/MA0GCSqG\n\
SIb3DQEBCwUAA4IBAQCAUlRhKneAU0SpgG1F/w0lfRqPI5NTdDUSb/AuIOrtgGNp\n\
iOYMoUkw4ILbaA9+hKz//3tC+n4vslKf0nleNRInNrzfllhEllXISpQCX0qd3NM6\n\
922si3lu/L6PI1hqivU4CkL2mHSIUy4Cr+EOvm/MdDN87LTLp0ltgkJP63MpwzIA\n\
KxX4iHqPbSAbrmVfxdCK0eJkbaOo/mThqVvm0CPWAnJa7AOOh2cZjeSomRXBPZFI\n\
mY3+rhy/9igbRb6t73KDmvbHO1GjbnpzvYOql/1jtPRrHBSBmu8UJNPhi/QEBIRU\n\
D2GiqPJQNwwXDLzgwoSF9AuuAMqfJ+JETxULix20\n\
-----END CERTIFICATE-----\n\n"};

5 (edited by zhq0918 2019-05-29 02:01:26)

Re: how can i load the certificate chain in client?

The same code out enclave executed success, but in enclave executed failed. In enclave, it reported " No PEM Header Error ".
and i found a new problem, when i executed the function which named wolfSSL_check_domain_name, no matter what the Dn is,the returned value is ssl_success.

Share

Re: how can i load the certificate chain in client?

zhq0918,

Is this for a commercial project or something else? Perhaps the best way for us to assist you on this is to get you under a support agreement so we can setup a technical call to work through your issues. Where are you located in the world? I can have one of our Business managers reach out to you directly to setup an intro call and discuss a more optimal path forward in your work with the SGX solution.

Warm Regards,

K

7 (edited by zhq0918 2019-05-29 18:42:53)

Re: how can i load the certificate chain in client?

Hi,@Kaleb, thank your response.There is no formal business projects.Maybe many of my questions i asked not clear.Let me summarize.Now,I'm learning sgx and wolfssl, i want to try to use the wolfssl to implement mutual verification,and i learned this by sgx-ra-tls.Now the main problem is that i want verify the client certificate,the server is in sgx enclave with wolfssl , the main funuctions that i wanted verify client certificate in sgx enclave were: wolfSSL_get_peer_certificate,wolfSSL_X509_verify_cert,wolfSSL_get_verify_result,etc.Except thease functions, i tested other function in sgx enclave too,such as:wolfSSL_CertManagerVerifyBuffer,wolfSSL_get_peer_chain,wolfSSL_check_domain_name,wolfSSL_X509_notAfter etc.I'm always asking questions about the testing process.I learned the manual of wolfssl. I knew the function named wolfSSL_get_verify_result is used to get the results after trying to verify the peer's certificate,the function named wolfSSL_X509_verify_cert is used to verifies certificate chain in ctx.My main tested fuction were wolfSSL_get_verify_result and  wolfSSL_X509_verify_cert,but the two functions were executed failed. the client main code which used openssl as flows:

    SSL_load_error_strings();
    ERR_load_crypto_strings();
    OpenSSL_add_all_algorithms();
    SSL_library_init();
    const SSL_METHOD *meth = NULL;
    meth = TLSv1_2_client_method();

    SSL_CTX *ctx = SSL_CTX_new(meth);
    assert(ctx != NULL);
 
    if (SSL_CTX_use_certificate_chain_file(ctx,CA_CHAIN_FILE) != 1){
        SSL_CTX_free(ctx);
        printf("Failed to load client certificate from %s", CA_CHAIN_FILE);
    }   
    if (SSL_CTX_load_verify_locations(ctx, CA_FILE, NULL) != 1) {
        SSL_CTX_free(ctx);
        printf("Failed to load CA file %s", CA_FILE);
    }
    if (SSL_CTX_set_default_verify_paths(ctx) != 1) {
        SSL_CTX_free(ctx);
        printf("Call to SSL_CTX_set_default_verify_paths failed");
    }
    if (SSL_CTX_use_certificate_file(ctx, CLIENT_CERT, SSL_FILETYPE_PEM) != 1) {
        SSL_CTX_free(ctx);
        printf("Failed to load client certificate from %s\n", CLIENT_KEY);
    }
    if (SSL_CTX_use_PrivateKey_file(ctx, CLIENT_KEY, SSL_FILETYPE_PEM) != 1) {
        SSL_CTX_free(ctx);
        printf("Failed to load client private key from %s\n", CLIENT_KEY);
    }
    if (SSL_CTX_check_private_key(ctx) != 1) {
         SSL_CTX_free(ctx);
         printf("SSL_CTX_check_private_key failed");
    }   
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, &verify_callback);
    In server, The main code which used wolfssl is :
    1)wolfSSL_X509_verify_cert, i write it in verifyCallback function as flows:
    int verifyCallback(int preverify, WOLFSSL_X509_STORE_CTX* store){
        (void) preverify; // unused
        int ret = WOLFSSL_SUCCESS; 
       
        ret = wolfSSL_X509_verify_cert(store);//This function verifies certificate chain in ctx.
        if (ret == WOLFSSL_FATAL_ERROR){
            printf("Verifies certificate chain in ctx failed!!\n");
        }
        else{
            printf("Verifies certificate chain in ctx success!!\n");
        }   
        return ret;
    }
    2)wolfSSL_get_verify_result,i write like this:
    int enc_verifyCertificate(WOLFSSL* ssl){
        long ret;
        if (sgx_is_within_enclave(ssl, sizeof(int)) != 1)
            abort();
        ret = wolfSSL_get_verify_result(ssl);//error info refrenced:https://linux.die.net/man/1/verify x509_v_ok = 0
        if( ret != X509_V_OK){
           printf("\tClient Authentication error, and the return value is %d\n",ret);
           return ret;
        }
        else
           return ret;
    }//The certificate chain i have tested the client certificate ok by openssl verify
   
    Please help me checked it, Is there something wrong with it?.

Share

Re: how can i load the certificate chain in client?

In the code you shared I still see API's ending in

_file

. The suggestion was to instead try utilizing the

_buffer

methods unless you have written out calls for file operations.

- K

9 (edited by zhq0918 2019-05-30 17:34:25)

Re: how can i load the certificate chain in client?

I know your mean. In server side,my code in enclave is as flows:
void testwolfSSL_CTX_load_verify_buffer(){
    WOLFSSL_METHOD* method = wolfTLSv1_2_server_method();
    WOLFSSL_CTX* ctx= wolfSSL_CTX_new(method);
    const unsigned char caCertBuf[] = {
    "-----BEGIN CERTIFICATE-----\
    MIIFizCCA3OgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwXTELMAkGA1UEBhMCQ04x\
    EDAOBgNVBAgMB0JlaUppbmcxEDAOBgNVBAcMB0JlaUppbmcxETAPBgNVBAoMCE1Z\
    Uk9PVENBMRcwFQYDVQQDDA4xMC4xMTMuMjE1LjE1NDAeFw0xOTA1MjUwOTQxMTVa\
    Fw0yOTA1MjIwOTQxMTVaMFIxCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdCZWlKaW5n\
    MREwDwYDVQQKDAhNWVJPT1RDQTEeMBwGA1UEAwwVd3d3LnpoYW5naHVpcWlhbmcu\
    Y29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArjHfrT6cQOShjI7a\
    HZr33BwEnKNiH//5+FceWY+AsKIXXRp/FD3UolCdP6od1hqQl5fhOLCgJdczMXXj\
    bYB9EtgatB0Ubd6EPfGC4+zkry7CDGVnJof3Ss2DRrSV3HzBum3yUzvTooczLkgy\
    PteldNGmK9KMxe2KG5bTSE72rszhVsvIEXwk/AOSp5xaCSo+wBPaOExpvpHUerrG\
    oJS/Q13L17PcHLgnq6F8fr4ZaCQzBp8RYtkfvzJOu9z3JYHLLMeeFa5+Sn48HrVj\
    H+szXgQHTn1Bigb0vJ7P7z3mckjqoKLtTI4LKitmRR8+7SSrEbRA+Gx57aohi6LN\
    68t8GrxXYJdlQW0y/QICSBo0gP8da117Yf8Gg7GJLCjB3yCXhrVRmV0mAsiTQEEE\
    9Q7HnXQNp/HCzrwV2R7B9mP2L1sVc8mZNoguPKTuTIchtuM/yF7kn6DuXa21WEWE\
    04entNv7vbkmUe+zUovuLPIsoLPf60JSQKc2nriNml0mEwxNxrdR3nfKZPbd4UIX\
    WWiCs2afZaBBsz2NgGMyv498QjP6OrFyR4Van14i2OrnCZ/ifSvTh7ohWTGnvf47\
    5/WG5gORYq5q7KXNxvAsSH0ulVZQqPYeyrWD0X0z7V1T/18+hXMQ//bWiYCP4nDX\
    8/zPXN3Tc/LexVErVo0fPBIEP8UCAwEAAaNgMF4wHQYDVR0OBBYEFNXtGFGQ3om1\
    ChmDRfcUviVbD4MAMB8GA1UdIwQYMBaAFAFF39PlvqEOu4FXIySHWeOiQ1K3MA8G\
    A1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBv\
    mKyrDwavrXJrAKbEP+ytctivp6D6NTaGZgmTVOKFfteHXBlO/IJm3ycPu2i/bppL\
    T2L63NZjXpxSV6tUdsab13xHiA7g2e4iajwztdvkscim1vydeNJsf5KAkMguu/e+\
    n3Vqo55xEmbpf6JQAt5s5qjCrp5PrcvGb0tIrLraHf/z6AvEWtRZv5HnRkwCc4W7\
    /d3QX+B0JFiOhsL3mzdvcjg3Bd6mu3wsrOHcH+ziZuH74z991S30u93PK/r1A8Tx\
    pPZdm3OOkT99+r8/+D0xjnXusJfCHQFapVRMnB/Gy2teleRqs5rhPwo5A9N2z69+\
    GmzRBi4nD6/sc+COYBWhZwqXSgHLVYpDWnaBM69jqbrg1MnIcrpbHb8RAt4mTRwT\
    P3oVsLaP0OOvCGngqxCCcKG54PpG0QlGaV1GMSk4b2AFXc3zBvuZcaBxGuJ+f6m+\
    NuT6JPT1/oNHV9VRXsVt/EW7daBghjgQmQLlh1T6JhU8lTXcQZAx9gAgqpi27EtW\
    KbSrFPQS6YZuBaH1U+fCAG7PIPFHIEhPdiXH1XyYxtLgazqN1iOLPm8DQ/RsTesm\
    k4Efd4ZgQcoNnuzNhanTGW/SPG8+hw0Jw2sC9qA60x3JFj4V5di/HYy4H/zk0DPt\
    H8V+fsb+K41kSwM28SsGJC6mgoMPtJrjRWVPoJkovQ==\
    -----END CERTIFICATE-----\
    "};
    const int certBufSz = (int) sizeof(caCertBuf);
    int ret = wolfSSL_CTX_load_verify_buffer(ctx,caCertBuf, certBufSz ,SSL_FILETYPE_PEM);//-372,   // no PEM header found /
    if (ret == SSL_SUCCESS){
      printf("test wolfSSL_CTX_load_verify_buffer success.\n");
    }
    else
       printf("test wolfSSL_CTX_load_verify_buffer ret=%d\t%s\t%d\n",ret,wolfSSL_ERR_reason_error_string(ret),__LINE__);
}
this code was executed out enclave success, but when executed in enclave,it reported the error code is -372.
Best Regards
zhq0918

Share

Re: how can i load the certificate chain in client?

Please try using the updated format I sent previously with return lines hard-coded.

- KH

11 (edited by zhq0918 2019-05-30 23:25:47)

Re: how can i load the certificate chain in client?

@Kaleb, i have tried the two formats that you gave me,they all success out enclave, unfortunately , in enclave,all reported "-372 no pem header".And i tested the function which name wolfSSL_CTX_trust_peer_buffer,the same result as wolfSSL_CTX_load_verify_buffer.
Best Regards
zhq0918

Share

Re: how can i load the certificate chain in client?

@zhq0918,

If successful outside the enclave then should work just fine inside the enclave IF the enclave has the exact same configuration. Do me a favor check what is in the header wolfssl/options.h outside the enclave where the tests pass and compare that to the SGX makefiles (all three, sgx_t_static.mk, sgx_t.mk, sgx_u.mk). For each wolfSSL specific setting in wolfssl/options.h add it to the Wolfssl_C_Extra_Flags in all three makefiles:

Wolfssl_C_Extra_Flags := -DWOLFSSL_SGX
Wolfssl_C_Extra_Flags += -D<OTHER SETTING FROM wolfssl/options.h>
Wolfssl_C_Extra_Flags += -D<next setting.. and so on>...

Get the two identically configured so that the test outside that succeeds is a true comparison to the test inside that is failing.

Warm Regards,

K

13 (edited by zhq0918 2019-06-03 19:48:31)

Re: how can i load the certificate chain in client?

Hi,@Kaleb, I have tried ,I checked the variable in three file you mentioned,I modified the Wolfssl_C_Extra_Flags in sgx_t_static.mk as flows:
Wolfssl_C_Extra_Flags := -DWOLFSSL_SGX
Wolfssl_C_Extra_Flags += -DWOLFSSL_SGX_ATTESTATION
Wolfssl_C_Extra_Flags += -DUSER_TIME
Wolfssl_C_Extra_Flags += -DWOLFSSL_CERT_EXT
Wolfssl_C_Extra_Flags += -DKEEP_PEER_CERT
Wolfssl_C_Extra_Flags += -DSESSION_CERTS
Wolfssl_C_Extra_Flags += -DSHOW_CERTS
Wolfssl_C_Extra_Flags += -DKEEP_OUR_CERT
Wolfssl_C_Extra_Flags += -DOPENSSL_EXTRA
Wolfssl_C_Extra_Flags += -DHAVE_LIGHTY
Wolfssl_C_Extra_Flags += -DWOLFSSL_TRUST_PEER_CERT
Wolfssl_C_Extra_Flags += -DHAVE_THREAD_LS
Wolfssl_C_Extra_Flags += -DHAVE_WRITE_DUP
Wolfssl_C_Extra_Flags += -DWOLFSSL_SHA512
Wolfssl_C_Extra_Flags += -DHAVE_ONE_TIME_AUTH
Wolfssl_C_Extra_Flags += -DHAVE_CHACHA
Wolfssl_C_Extra_Flags += -DHAVE_HASHDRBG
Wolfssl_C_Extra_Flags += -DHAVE_TLS_EXTENSIONS
Wolfssl_C_Extra_Flags += -DHAVE_SUPPORTED_CURVES
Wolfssl_C_Extra_Flags += -DHAVE_EXTENDED_MASTER
Wolfssl_C_Extra_Flags += -D_POSIX_THREADS
Wolfssl_C_Extra_Flags += -DWOLFSSL_SHA384
Wolfssl_C_Extra_Flags += -DNO_DSA
Wolfssl_C_Extra_Flags += -DTFM_ECC256
Wolfssl_C_Extra_Flags += -DECC_SHAMIR
Wolfssl_C_Extra_Flags += -DWOLFSSL_BASE64_ENCODE
Wolfssl_C_Extra_Flags += -DWOLFSSL_ALLOW_TLSV10
Wolfssl_C_Extra_Flags += -DNO_RC4
Wolfssl_C_Extra_Flags += -DNO_HC128
Wolfssl_C_Extra_Flags += -DNO_RABBIT
Wolfssl_C_Extra_Flags += -DWOLFSSL_SHA224
Wolfssl_C_Extra_Flags += -DWOLFSSL_SHA3
Wolfssl_C_Extra_Flags += -DHAVE_POLY1305
Wolfssl_C_Extra_Flags += -DNO_PSK
Wolfssl_C_Extra_Flags += -DNO_MD4
Wolfssl_C_Extra_Flags += -DNO_PWDBASED
Wolfssl_C_Extra_Flags += -DWOLFSSL_X86_64_BUILD
Wolfssl_C_Extra_Flags += -DWC_NO_ASYNC_THREADING
Wolfssl_C_Extra_Flags += -DNO_DES3

I modified the Wolfssl_C_Extra_Flags in sgx_t.mk and sgx_u.mk all as flows:
Wolfssl_C_Extra_Flags := -DSGX_SDK -DWOLFSSL_SGX -DWOLFSSL_SGX_ATTESTATION -DUSER_TIME -DWOLFSSL_CERT_EXT -DKEEP_PEER_CERT -DSESSION_CERTS -DSHOW_CERTS -DKEEP_OUR_CERT -DOPENSSL_EXTRA -DHAVE_LIGHTY -DWOLFSSL_TRUST_PEER_CERT -DHAVE_THREAD_LS -DHAVE_WRITE_DUP -DWOLFSSL_SHA512 -DHAVE_ONE_TIME_AUTH -DHAVE_CHACHA -DHAVE_HASHDRBG -DHAVE_TLS_EXTENSIONS -DHAVE_SUPPORTED_CURVES -DHAVE_EXTENDED_MASTER -D_POSIX_THREADS -DWOLFSSL_SHA384 -DNO_DSA -DTFM_ECC256 -DECC_SHAMIR -DWOLFSSL_BASE64_ENCODE -DWOLFSSL_ALLOW_TLSV10 -DNO_RC4 -DNO_HC128 -DNO_RABBIT -DWOLFSSL_SHA224 -DWOLFSSL_SHA3 -DHAVE_POLY1305 -DNO_PSK -DNO_MD4 -DNO_PWDBASED -DWOLFSSL_X86_64_BUILD -DWC_NO_ASYNC_THREADING -DNO_DES3
I added the other macro variable in wolfssl/options.h to the variable which named Wolfssl_C_Extra_Flags,when i builded, it would reported warning such as :.../wolfssl/wolfcrypt/settings.hwarning:1217:0:warning:"HAVE_ECC" redefined",so i didn't the macro like "HAVE_ECC"、"ECC_TIMING_RESISTANT"、"WC_RSA_BLINDING"、"HAVE_AESGCM" etc. 

Unfortunately,when i executed the app,the function wolfSSL_CTX_load_verify_buffer reported the same error:-372 No PEM Header Error.what i did was missing?
    Can you test the function which named enc_wolfSSL_CTX_load_verify_buffer in wolfssl_enclave.c in the project sgx-ra-tls ?


Best Regards
zhq0918

Share

14 (edited by zhq0918 2019-06-03 23:37:47)

Re: how can i load the certificate chain in client?

Today, i checked the source code which name ssl.c in deps\wolfssl\src.The function PemtoDer, as flows:
int PemToDer(const unsigned char* buff, long longSz, int type,
              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
{
    const char* header      = NULL;
    const char* footer      = NULL;
    char*       headerEnd;
    char*       footerEnd;
    char*       consumedEnd;
    char*       bufferEnd   = (char*)(buff + longSz);
    long        neededSz;
    int         ret         = 0;
    int         sz          = (int)longSz;
    int         encrypted_key = 0;
    DerBuffer*  der;

    WOLFSSL_ENTER("PemToDer");

    switch (type) {
        case CA_TYPE:       /* same as below */
        case TRUSTED_PEER_TYPE:

        case CERT_TYPE:      header=BEGIN_CERT;       footer=END_CERT;
                             break;
        case CRL_TYPE:       header=BEGIN_X509_CRL;   footer=END_X509_CRL;
                             break;
        case DH_PARAM_TYPE:  header=BEGIN_DH_PARAM;   footer=END_DH_PARAM;
                             break;
        case DSA_PARAM_TYPE: header=BEGIN_DSA_PARAM;  footer=END_DSA_PARAM;
                             break;
        case CERTREQ_TYPE:   header=BEGIN_CERT_REQ;   footer=END_CERT_REQ;
                             break;
        case DSA_TYPE:       header=BEGIN_DSA_PRIV;   footer=END_DSA_PRIV;
                             break;
        case ECC_TYPE:       header=BEGIN_EC_PRIV;    footer=END_EC_PRIV;
                             break;
        case RSA_TYPE:       header=BEGIN_RSA_PRIV;   footer=END_RSA_PRIV;
                             break;
        case ED25519_TYPE:   header=BEGIN_EDDSA_PRIV; footer=END_EDDSA_PRIV;
                             break;
        case PUBLICKEY_TYPE: header=BEGIN_PUB_KEY;    footer=END_PUB_KEY;
                             break;
        default:             header=BEGIN_RSA_PRIV;   footer=END_RSA_PRIV;
                             break;
    }

    /* find header */
    for (;;) {
        headerEnd = XSTRNSTR((char*)buff, header, sz);

        if (headerEnd || type != PRIVATEKEY_TYPE) {
            break;
        } else if (header == BEGIN_RSA_PRIV) {
                   header =  BEGIN_PRIV_KEY;       footer = END_PRIV_KEY;
        } else if (header == BEGIN_PRIV_KEY) {
                   header =  BEGIN_ENC_PRIV_KEY;   footer = END_ENC_PRIV_KEY;
        } else if (header == BEGIN_ENC_PRIV_KEY) {
                   header =  BEGIN_EC_PRIV;        footer = END_EC_PRIV;
        } else if (header == BEGIN_EC_PRIV) {
                   header =  BEGIN_DSA_PRIV;       footer = END_DSA_PRIV;
        } else if (header == BEGIN_DSA_PRIV) {
                   header =  BEGIN_EDDSA_PRIV;     footer = END_EDDSA_PRIV;
        } else
            break;
    }

    if (!headerEnd) {
        WOLFSSL_MSG("Couldn't find PEM header");
        return SSL_NO_PEM_HEADER;
    }

    headerEnd += XSTRLEN(header);

    if ((headerEnd + 1) >= bufferEnd)
        return WOLFSSL_BAD_FILE;

    /* eat end of line */
    if (headerEnd[0] == '\n')
        headerEnd++;
    else if (headerEnd[1] == '\n')
        headerEnd += 2;
    else {
        if (info)
            info->consumed = (long)(headerEnd+2 - (char*)buff);
        return WOLFSSL_BAD_FILE;
    }

    if (type == PRIVATEKEY_TYPE) {
        if (eccKey)
            *eccKey = header == BEGIN_EC_PRIV;
    }

#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
    {
        /* remove encrypted header if there */
        const char* const encHeader = "Proc-Type";
        word32 headerEndSz = (word32)(bufferEnd - headerEnd);
        char* line         = XSTRNSTR(headerEnd, encHeader, min(headerEndSz,
                                                                PEM_LINE_LEN));
        if (line != NULL) {
            word32 lineSz;
            char*  finish;
            word32 finishSz;
            char*  start;
            word32 startSz;
            char*  newline;

            if (line >= bufferEnd) {
                return WOLFSSL_BAD_FILE;
            }

            lineSz = (word32)(bufferEnd - line);
            start = XSTRNSTR(line, "DES", min(lineSz, PEM_LINE_LEN));

            if (start == NULL) {
                start = XSTRNSTR(line, "AES", min(lineSz, PEM_LINE_LEN));
            }

            if (start == NULL) return WOLFSSL_BAD_FILE;
            if (info == NULL)  return WOLFSSL_BAD_FILE;

            if (start >= bufferEnd) {
                return WOLFSSL_BAD_FILE;
            }

            startSz = (word32)(bufferEnd - start);
            finish = XSTRNSTR(start, ",", min(startSz, PEM_LINE_LEN));

            if ((start != NULL) && (finish != NULL) && (start < finish)) {
                if (finish >= bufferEnd) {
                    return WOLFSSL_BAD_FILE;
                }

                finishSz = (word32)(bufferEnd - finish);
                newline = XSTRNSTR(finish, "\r", min(finishSz, PEM_LINE_LEN));

                if (NAME_SZ < (finish - start)) /* buffer size of info->name*/
                    return BUFFER_E;
                if (XMEMCPY(info->name, start, finish - start) == NULL)
                    return WOLFSSL_FATAL_ERROR;
                info->name[finish - start] = 0;
                if (finishSz < sizeof(info->iv) + 1)
                    return BUFFER_E;
                if (XMEMCPY(info->iv, finish + 1, sizeof(info->iv)) == NULL)
                    return WOLFSSL_FATAL_ERROR;

                if (newline == NULL)
                    newline = XSTRNSTR(finish, "\n", min(finishSz,
                                                         PEM_LINE_LEN));
                if ((newline != NULL) && (newline > finish)) {
                    info->ivSz = (word32)(newline - (finish + 1));
                    info->set = 1;
                }
                else
                    return WOLFSSL_BAD_FILE;
            }
            else
                return WOLFSSL_BAD_FILE;

            /* eat blank line */
            while (*newline == '\r' || *newline == '\n')
                newline++;
            headerEnd = newline;

            encrypted_key = 1;
        }
    }
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */

    /* find footer */
    footerEnd = XSTRNSTR((char*)buff, footer, sz);
    if (!footerEnd) {
        if (info)
            info->consumed = longSz; /* No more certs if no footer */
        return WOLFSSL_BAD_FILE;
    }

    consumedEnd = footerEnd + XSTRLEN(footer);

    if (consumedEnd < bufferEnd) {  /* handle no end of line on last line */
        /* eat end of line */
        if (consumedEnd[0] == '\n')
            consumedEnd++;
        else if ((consumedEnd + 1 < bufferEnd) && consumedEnd[1] == '\n')
            consumedEnd += 2;
        else {
            if (info)
                info->consumed = (long)(consumedEnd+2 - (char*)buff);
            return WOLFSSL_BAD_FILE;
        }
    }

    if (info)
        info->consumed = (long)(consumedEnd - (char*)buff);

    /* set up der buffer */
    neededSz = (long)(footerEnd - headerEnd);
    if (neededSz > sz || neededSz <= 0)
        return WOLFSSL_BAD_FILE;

    ret = AllocDer(pDer, (word32)neededSz, type, heap);
    if (ret < 0) {
        return ret;
    }
    der = *pDer;

    if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
                      der->buffer, &der->length) < 0)
        return WOLFSSL_BAD_FILE;

    if (header == BEGIN_PRIV_KEY && !encrypted_key) {
        /* pkcs8 key, convert and adjust length */
        if ((ret = ToTraditional(der->buffer, der->length)) < 0)
            return ret;

        der->length = ret;
        return 0;
    }

#if (defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)) && !defined(NO_PWDBASED)
    if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
        int   passwordSz;
    #ifdef WOLFSSL_SMALL_STACK
        char* password = NULL;
    #else
        char  password[80];
    #endif

        if (!info || !info->ctx || !info->ctx->passwd_cb)
            return WOLFSSL_BAD_FILE;  /* no callback error */

    #ifdef WOLFSSL_SMALL_STACK
        password = (char*)XMALLOC(80, heap, DYNAMIC_TYPE_STRING);
        if (password == NULL)
            return MEMORY_E;
    #endif
        passwordSz = info->ctx->passwd_cb(password, sizeof(password), 0,
                                          info->ctx->userdata);
        /* convert and adjust length */
        if (header == BEGIN_ENC_PRIV_KEY) {
            ret = ToTraditionalEnc(der->buffer, der->length,
                                   password, passwordSz);
    #ifdef WOLFSSL_SMALL_STACK
            XFREE(password, NULL, DYNAMIC_TYPE_STRING);
    #endif
            if (ret < 0) {
                return ret;
            }

            der->length = ret;
        }
        /* decrypt the key */
        else {
            ret = wolfssl_decrypt_buffer_key(der, (byte*)password,
                                             passwordSz, info);
    #ifdef WOLFSSL_SMALL_STACK
            XFREE(password, heap, DYNAMIC_TYPE_STRING);
    #endif
            if (ret != WOLFSSL_SUCCESS) {
                return ret;
            }
        }
    }
#endif  /* OPENSSL_EXTRA || HAVE_WEBSERVER || NO_PWDBASED */

    return 0;
}

when the type is CA_TYPE and TRUSTED_PEER_TYPE, no deal?

Share

Re: how can i load the certificate chain in client?

@zhq0918,

Can you please reach out to Rich Kelm (rich@wolfssl.com) directly to discuss how we can best continue supporting your efforts.

Thanks!

Regards,

K

16 (edited by zhq0918 2019-06-05 22:49:10)

Re: how can i load the certificate chain in client?

@Kaleb, thank you. Now i have tried traced the code, and i found that, when executed  the function  which named enc_wolfSSL_CTX_load_verify_buffer, the call order of function is enc_wolfSSL_CTX_load_verify_buffer->wolfSSL_CTX_load_verify_buffer->...->ValidateDate->XTIME.And the function XTIME in wolfssl-ra-attester.c,like this:
#ifdef WOLFSSL_SGX
time_t XTIME(time_t* tloc) {
    time_t x = 1512498557; /* Dec 5, 2017, 10:29 PDT */Should this be a timestamp of the current time?
    if (tloc) *tloc = x;
    return x;
}

time_t mktime(struct tm* tm) {
    (void) tm;
    assert(0);
    return (time_t) 0;
}
#endif

Is the value of x fixed?I think this is the reason why I called the function enc_wolfSSL_CTX_load_verify_buffer,its reported "ASN date error, current date before",i changed it,now the problem has been resolved.

Regards

zhq0918

Share