picoquic/tls_api.c
int picoquic_master_tlscontext(picoquic_quic_t* quic,
    char const* cert_file_name, char const* key_file_name, const char * cert_root_file_name,
    const uint8_t* ticket_key, size_t ticket_key_length)
{
    /* Create a client context or a server context */
    int ret = 0;
    ptls_context_t* ctx;
    ptls_openssl_verify_certificate_t* verifier = NULL;
    ptls_on_client_hello_t* och = NULL;
    ptls_encrypt_ticket_t* encrypt_ticket = NULL;
    ptls_save_ticket_t* save_ticket = NULL;

    picoquic_init_openssl(); /* OpenSSL init, just in case */

    ctx = (ptls_context_t*)malloc(sizeof(ptls_context_t));

    if (ctx == NULL) {
        ret = -1;
    } else {
        memset(ctx, 0, sizeof(ptls_context_t));
        ctx->random_bytes = ptls_openssl_random_bytes;
        ctx->key_exchanges = picoquic_key_exchanges; /* was:  ptls_openssl_key_exchanges; */
        ctx->cipher_suites = picoquic_cipher_suites; /* was: ptls_openssl_cipher_suites; */

        ctx->send_change_cipher_spec = 0;

        ctx->hkdf_label_prefix__obsolete = NULL;
        ctx->update_traffic_key = picoquic_set_update_traffic_key_callback();

        if (quic->p_simulated_time == NULL) {
            ctx->get_time = &ptls_get_time;
        } else {
            ptls_get_time_t* time_getter = (ptls_get_time_t*)malloc(sizeof(ptls_get_time_t) + sizeof(uint64_t*));
            if (time_getter == NULL) {
                ret = PICOQUIC_ERROR_MEMORY;
            } else {
                uint64_t** pp_simulated_time = (uint64_t**)(((char*)time_getter) + sizeof(ptls_get_time_t));

                time_getter->cb = picoquic_get_simulated_time_cb;
                *pp_simulated_time = quic->p_simulated_time;
                ctx->get_time = time_getter;
            }
        }

        if (cert_file_name != NULL && key_file_name != NULL) {
            /* Read the certificate file */
            if (ptls_load_certificates(ctx, (char*)cert_file_name) != 0) {
                ret = -1;
            } else {
                ret = set_sign_certificate_from_key_file(key_file_name, ctx);
            }
        }

        if (ret == 0) {
            och = (ptls_on_client_hello_t*)malloc(sizeof(ptls_on_client_hello_t) + sizeof(picoquic_quic_t*));
            if (och != NULL) {
                picoquic_quic_t** ppquic = (picoquic_quic_t**)(((char*)och) + sizeof(ptls_on_client_hello_t));

                och->cb = picoquic_client_hello_call_back;
                ctx->on_client_hello = och;
                *ppquic = quic;
            } else {
                ret = PICOQUIC_ERROR_MEMORY;
            }
        }

        if (ret == 0) {
            ret = picoquic_server_setup_ticket_aead_contexts(quic, ctx, ticket_key, ticket_key_length);
        }

        if (ret == 0) {
            encrypt_ticket = (ptls_encrypt_ticket_t*)malloc(sizeof(ptls_encrypt_ticket_t) + sizeof(picoquic_quic_t*));
            if (encrypt_ticket == NULL) {
                ret = PICOQUIC_ERROR_MEMORY;
            } else {
                picoquic_quic_t** ppquic = (picoquic_quic_t**)(((char*)encrypt_ticket) + sizeof(ptls_encrypt_ticket_t));

                encrypt_ticket->cb = picoquic_server_encrypt_ticket_call_back;
                *ppquic = quic;

                ctx->encrypt_ticket = encrypt_ticket;
                ctx->ticket_lifetime = 100000; /* 100,000 seconds, a bit more than one day */
                ctx->require_dhe_on_psk = 1;
                ctx->max_early_data_size = 0xFFFFFFFF;
            }
        }

        verifier = (ptls_openssl_verify_certificate_t*)malloc(sizeof(ptls_openssl_verify_certificate_t));
        if (verifier == NULL) {
            ctx->verify_certificate = NULL;
        } else {
            X509_STORE *store = X509_STORE_new();

            if (cert_root_file_name != NULL && store != NULL) {
                int file_ret = 0;
                X509_LOOKUP* lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
                if ((file_ret = X509_LOOKUP_load_file(lookup, cert_root_file_name, X509_FILETYPE_PEM)) != 1) {
                    DBG_PRINTF("Cannot load X509 store (%s), ret = %d\n",
                        cert_root_file_name, ret);
                }
                else {
                    quic->is_cert_store_not_empty = 1;
                }
            }

            ptls_openssl_init_verify_certificate(verifier, store);
            ctx->verify_certificate = &verifier->super;

            // If we created an instance of the store, release our reference after giving it to the verify_certificate callback.
            // The callback internally increased the reference counter by one.
            if (store != NULL) {
#if OPENSSL_VERSION_NUMBER > 0x10100000L
                X509_STORE_free(store);
#endif
            }
        }

        if (quic->ticket_file_name != NULL) {
            save_ticket = (ptls_save_ticket_t*)malloc(sizeof(ptls_save_ticket_t) + sizeof(picoquic_quic_t*));
            if (save_ticket != NULL) {
                picoquic_quic_t** ppquic = (picoquic_quic_t**)(((char*)save_ticket) + sizeof(ptls_save_ticket_t));

                save_ticket->cb = picoquic_client_save_ticket_call_back;
                ctx->save_ticket = save_ticket;
                *ppquic = quic;
            }
        }

        if (ret == 0) {
            /* Tell Picotls to not require EOED messages during handshake */
            ctx->omit_end_of_early_data = 1;
        }

        if (ret == 0) {
            quic->tls_master_ctx = ctx;
            picoquic_public_random_seed(quic);
        } else {
            free(ctx);
        }
    }

    return ret;
}
/*
 * Setting the master TLS context.
 * On servers, this implies setting the "on hello" call back
 */
Setting the master TLS context.
On servers, this implies setting the "on hello" call back
Setting the master TLS context . On servers this implies setting the " on hello " call back
int picoquic_master_tlscontext(picoquic_quic_t* quic,
    char const* cert_file_name, char const* key_file_name, const char * cert_root_file_name,
    const uint8_t* ticket_key, size_t ticket_key_length)
{
    int ret = 0;
    ptls_context_t* ctx;
    ptls_openssl_verify_certificate_t* verifier = NULL;
    ptls_on_client_hello_t* och = NULL;
    ptls_encrypt_ticket_t* encrypt_ticket = NULL;
    ptls_save_ticket_t* save_ticket = NULL;
    picoquic_init_openssl(); 
    ctx = (ptls_context_t*)malloc(sizeof(ptls_context_t));
    if (ctx == NULL) {
        ret = -1;
    } else {
        memset(ctx, 0, sizeof(ptls_context_t));
        ctx->random_bytes = ptls_openssl_random_bytes;
        ctx->key_exchanges = picoquic_key_exchanges; 
        ctx->cipher_suites = picoquic_cipher_suites; 
        ctx->send_change_cipher_spec = 0;
        ctx->hkdf_label_prefix__obsolete = NULL;
        ctx->update_traffic_key = picoquic_set_update_traffic_key_callback();
        if (quic->p_simulated_time == NULL) {
            ctx->get_time = &ptls_get_time;
        } else {
            ptls_get_time_t* time_getter = (ptls_get_time_t*)malloc(sizeof(ptls_get_time_t) + sizeof(uint64_t*));
            if (time_getter == NULL) {
                ret = PICOQUIC_ERROR_MEMORY;
            } else {
                uint64_t** pp_simulated_time = (uint64_t**)(((char*)time_getter) + sizeof(ptls_get_time_t));
                time_getter->cb = picoquic_get_simulated_time_cb;
                *pp_simulated_time = quic->p_simulated_time;
                ctx->get_time = time_getter;
            }
        }
        if (cert_file_name != NULL && key_file_name != NULL) {
            if (ptls_load_certificates(ctx, (char*)cert_file_name) != 0) {
                ret = -1;
            } else {
                ret = set_sign_certificate_from_key_file(key_file_name, ctx);
            }
        }
        if (ret == 0) {
            och = (ptls_on_client_hello_t*)malloc(sizeof(ptls_on_client_hello_t) + sizeof(picoquic_quic_t*));
            if (och != NULL) {
                picoquic_quic_t** ppquic = (picoquic_quic_t**)(((char*)och) + sizeof(ptls_on_client_hello_t));
                och->cb = picoquic_client_hello_call_back;
                ctx->on_client_hello = och;
                *ppquic = quic;
            } else {
                ret = PICOQUIC_ERROR_MEMORY;
            }
        }
        if (ret == 0) {
            ret = picoquic_server_setup_ticket_aead_contexts(quic, ctx, ticket_key, ticket_key_length);
        }
        if (ret == 0) {
            encrypt_ticket = (ptls_encrypt_ticket_t*)malloc(sizeof(ptls_encrypt_ticket_t) + sizeof(picoquic_quic_t*));
            if (encrypt_ticket == NULL) {
                ret = PICOQUIC_ERROR_MEMORY;
            } else {
                picoquic_quic_t** ppquic = (picoquic_quic_t**)(((char*)encrypt_ticket) + sizeof(ptls_encrypt_ticket_t));
                encrypt_ticket->cb = picoquic_server_encrypt_ticket_call_back;
                *ppquic = quic;
                ctx->encrypt_ticket = encrypt_ticket;
                ctx->ticket_lifetime = 100000; 
                ctx->require_dhe_on_psk = 1;
                ctx->max_early_data_size = 0xFFFFFFFF;
            }
        }
        verifier = (ptls_openssl_verify_certificate_t*)malloc(sizeof(ptls_openssl_verify_certificate_t));
        if (verifier == NULL) {
            ctx->verify_certificate = NULL;
        } else {
            X509_STORE *store = X509_STORE_new();
            if (cert_root_file_name != NULL && store != NULL) {
                int file_ret = 0;
                X509_LOOKUP* lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
                if ((file_ret = X509_LOOKUP_load_file(lookup, cert_root_file_name, X509_FILETYPE_PEM)) != 1) {
                    DBG_PRINTF("Cannot load X509 store (%s), ret = %d\n",
                        cert_root_file_name, ret);
                }
                else {
                    quic->is_cert_store_not_empty = 1;
                }
            }
            ptls_openssl_init_verify_certificate(verifier, store);
            ctx->verify_certificate = &verifier->super;
            if (store != NULL) {
#if OPENSSL_VERSION_NUMBER > 0x10100000L
                X509_STORE_free(store);
#endif
            }
        }
        if (quic->ticket_file_name != NULL) {
            save_ticket = (ptls_save_ticket_t*)malloc(sizeof(ptls_save_ticket_t) + sizeof(picoquic_quic_t*));
            if (save_ticket != NULL) {
                picoquic_quic_t** ppquic = (picoquic_quic_t**)(((char*)save_ticket) + sizeof(ptls_save_ticket_t));
                save_ticket->cb = picoquic_client_save_ticket_call_back;
                ctx->save_ticket = save_ticket;
                *ppquic = quic;
            }
        }
        if (ret == 0) {
            ctx->omit_end_of_early_data = 1;
        }
        if (ret == 0) {
            quic->tls_master_ctx = ctx;
            picoquic_public_random_seed(quic);
        } else {
            free(ctx);
        }
    }
    return ret;
}
int picoquic_master_tlscontext ( picoquic_quic_t * quic , char const * cert_file_name , char const * key_file_name , const char * cert_root_file_name , const uint8_t * ticket_key , size_t ticket_key_length ) { int ret = 0 ; ptls_context_t * ctx ; ptls_openssl_verify_certificate_t * verifier = NULL ; ptls_on_client_hello_t * och = NULL ; ptls_encrypt_ticket_t * encrypt_ticket = NULL ; ptls_save_ticket_t * save_ticket = NULL ; picoquic_init_openssl ( ) ; ctx = ( ptls_context_t * ) malloc ( sizeof ( ptls_context_t ) ) ; if ( ctx == NULL ) { ret = -1 ; } else { memset ( ctx , 0 , sizeof ( ptls_context_t ) ) ; ctx -> random_bytes = ptls_openssl_random_bytes ; ctx -> key_exchanges = picoquic_key_exchanges ; ctx -> cipher_suites = picoquic_cipher_suites ; ctx -> send_change_cipher_spec = 0 ; ctx -> hkdf_label_prefix__obsolete = NULL ; ctx -> update_traffic_key = picoquic_set_update_traffic_key_callback ( ) ; if ( quic -> p_simulated_time == NULL ) { ctx -> get_time = & ptls_get_time ; } else { ptls_get_time_t * time_getter = ( ptls_get_time_t * ) malloc ( sizeof ( ptls_get_time_t ) + sizeof ( uint64_t * ) ) ; if ( time_getter == NULL ) { ret = PICOQUIC_ERROR_MEMORY ; } else { uint64_t * * pp_simulated_time = ( uint64_t * * ) ( ( ( char * ) time_getter ) + sizeof ( ptls_get_time_t ) ) ; time_getter -> cb = picoquic_get_simulated_time_cb ; * pp_simulated_time = quic -> p_simulated_time ; ctx -> get_time = time_getter ; } } if ( cert_file_name != NULL && key_file_name != NULL ) { if ( ptls_load_certificates ( ctx , ( char * ) cert_file_name ) != 0 ) { ret = -1 ; } else { ret = set_sign_certificate_from_key_file ( key_file_name , ctx ) ; } } if ( ret == 0 ) { och = ( ptls_on_client_hello_t * ) malloc ( sizeof ( ptls_on_client_hello_t ) + sizeof ( picoquic_quic_t * ) ) ; if ( och != NULL ) { picoquic_quic_t * * ppquic = ( picoquic_quic_t * * ) ( ( ( char * ) och ) + sizeof ( ptls_on_client_hello_t ) ) ; och -> cb = picoquic_client_hello_call_back ; ctx -> on_client_hello = och ; * ppquic = quic ; } else { ret = PICOQUIC_ERROR_MEMORY ; } } if ( ret == 0 ) { ret = picoquic_server_setup_ticket_aead_contexts ( quic , ctx , ticket_key , ticket_key_length ) ; } if ( ret == 0 ) { encrypt_ticket = ( ptls_encrypt_ticket_t * ) malloc ( sizeof ( ptls_encrypt_ticket_t ) + sizeof ( picoquic_quic_t * ) ) ; if ( encrypt_ticket == NULL ) { ret = PICOQUIC_ERROR_MEMORY ; } else { picoquic_quic_t * * ppquic = ( picoquic_quic_t * * ) ( ( ( char * ) encrypt_ticket ) + sizeof ( ptls_encrypt_ticket_t ) ) ; encrypt_ticket -> cb = picoquic_server_encrypt_ticket_call_back ; * ppquic = quic ; ctx -> encrypt_ticket = encrypt_ticket ; ctx -> ticket_lifetime = 100000 ; ctx -> require_dhe_on_psk = 1 ; ctx -> max_early_data_size = 0xFFFFFFFF ; } } verifier = ( ptls_openssl_verify_certificate_t * ) malloc ( sizeof ( ptls_openssl_verify_certificate_t ) ) ; if ( verifier == NULL ) { ctx -> verify_certificate = NULL ; } else { X509_STORE * store = X509_STORE_new ( ) ; if ( cert_root_file_name != NULL && store != NULL ) { int file_ret = 0 ; X509_LOOKUP * lookup = X509_STORE_add_lookup ( store , X509_LOOKUP_file ( ) ) ; if ( ( file_ret = X509_LOOKUP_load_file ( lookup , cert_root_file_name , X509_FILETYPE_PEM ) ) != 1 ) { DBG_PRINTF ( " \n " , cert_root_file_name , ret ) ; } else { quic -> is_cert_store_not_empty = 1 ; } } ptls_openssl_init_verify_certificate ( verifier , store ) ; ctx -> verify_certificate = & verifier -> super ; if ( store != NULL ) { #if OPENSSL_VERSION_NUMBER > 0x10100000L X509_STORE_free ( store ) ; #endif } } if ( quic -> ticket_file_name != NULL ) { save_ticket = ( ptls_save_ticket_t * ) malloc ( sizeof ( ptls_save_ticket_t ) + sizeof ( picoquic_quic_t * ) ) ; if ( save_ticket != NULL ) { picoquic_quic_t * * ppquic = ( picoquic_quic_t * * ) ( ( ( char * ) save_ticket ) + sizeof ( ptls_save_ticket_t ) ) ; save_ticket -> cb = picoquic_client_save_ticket_call_back ; ctx -> save_ticket = save_ticket ; * ppquic = quic ; } } if ( ret == 0 ) { ctx -> omit_end_of_early_data = 1 ; } if ( ret == 0 ) { quic -> tls_master_ctx = ctx ; picoquic_public_random_seed ( quic ) ; } else { free ( ctx ) ; } } return ret ; }
Setting the master TLS context.
Setting the master TLS context .
/* Create a client context or a server context */ /* OpenSSL init, just in case */ /* was:  ptls_openssl_key_exchanges; */ /* was: ptls_openssl_cipher_suites; */ /* Read the certificate file */ /* 100,000 seconds, a bit more than one day */ // If we created an instance of the store, release our reference after giving it to the verify_certificate callback. // The callback internally increased the reference counter by one. /* Tell Picotls to not require EOED messages during handshake */