Sorry for the mistake. here is the attachment again
/*
 *  Created by Gavriloaie Eugen-Andrei (shir...@gmail.com)
 *
 * The logical steps:
 * 1. initialize the SSL library
 * 2. creates an X509 key and cert
 * 3. creates an DTLS server SSL context
 * 4. Setup 2 memory BIO instances on the SSL context
 * 5. Feed the input BIO with a hardcoded "Client Hello" packet
 * 6. Call SSL_accept
 *
 * Wanted:
 * The output BIO should contain a packet ("Server Hello") to be sent over the 
wire
 *
 * Observed on OpenSSL 1.0.1k:
 * The output BIO is empty, the handshake never succeeds
 */

#include <openssl/conf.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <openssl/rand.h>
#include <openssl/err.h>
#include <openssl/engine.h>
#include <assert.h>

#define X509_KEY_SIZE 1024

void InitSSL();
void CleanupSSL();
EVP_PKEY * CreateCertificateKey();
X509 * CreateCertificate(EVP_PKEY *pKey);

int main(void) {
        //first, init the OpenSSL library
        InitSSL();

        //define a "Client Hello"
        unsigned char buffer[] = {
                0x16, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x6d, 0x01, 0x00, 0x00,
                0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x61, 0xfe, 0xff, 0xa1, 0xe1, 0xcb, 0x7f, 0x76,
                0xb9, 0x42, 0x7c, 0x97, 0xaa, 0x1e, 0x9f, 0x5e,
                0x18, 0x62, 0xe1, 0xe0, 0x29, 0x7b, 0xdc, 0xf3,
                0x57, 0x02, 0x89, 0xab, 0x82, 0x80, 0x91, 0x63,
                0x33, 0x98, 0xce, 0x00, 0x00, 0x00, 0x18, 0xc0,
                0x14, 0xc0, 0x0a, 0x00, 0x39, 0x00, 0x35, 0xc0,
                0x19, 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x33, 0x00,
                0x2f, 0xc0, 0x18, 0x00, 0x0a, 0x00, 0xff, 0x01,
                0x00, 0x00, 0x1f, 0x00, 0x23, 0x00, 0x00, 0x00,
                0x0e, 0x00, 0x05, 0x00, 0x02, 0x00, 0x01, 0x00,
                0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a,
                0x00, 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18,
                0x00, 0x19
        };

        X509 *pX509 = NULL;
        EVP_PKEY *pX509Key = NULL;
        SSL_CTX *pSslContext = NULL;
        SSL *pSSL = NULL;
        BIO *pNetToSSLBIO = NULL;
        BIO *pSSLToNetBIO = NULL;
        BUF_MEM *pSSLBuffer = NULL;

        //initialize the X509 key and cert
        pX509Key = CreateCertificateKey();
        assert(pX509Key != NULL);
        pX509 = CreateCertificate(pX509Key);
        assert(pX509 != NULL);

        //create a SSL context blueprint and setup the X509 key and cert into it
        pSslContext = SSL_CTX_new(DTLSv1_server_method());
        assert(pSslContext != NULL);
        assert(SSL_CTX_use_certificate(pSslContext, pX509) == 1);
        assert(SSL_CTX_use_PrivateKey(pSslContext, pX509Key) == 1);
        assert(SSL_CTX_check_private_key(pSslContext) == 1);

        //create a SSL context using the blueprints above
        pSSL = SSL_new(pSslContext);
        assert(pSSL != NULL);

        //create 2 memory BIO to simulate the I/O

        //used to feed data FROM network TO SSL
        pNetToSSLBIO = BIO_new(BIO_s_mem());
        assert(pNetToSSLBIO != NULL);

        //used by SSL context to store data that needs to be eventually sent 
out to the network
        pSSLToNetBIO = BIO_new(BIO_s_mem());
        assert(pSSLToNetBIO != NULL);

        //set the BIOs into the SSL context
        SSL_set_bio(pSSL, pNetToSSLBIO, pSSLToNetBIO);

        //simulate network input by appending the data to the input BIO
        assert(BIO_write(pNetToSSLBIO, buffer, sizeof (buffer)) == sizeof 
(buffer));
        BIO_get_mem_ptr(pNetToSSLBIO, &pSSLBuffer);
        assert((pSSLBuffer != NULL)&&(pSSLBuffer->length == sizeof (buffer)));

        //call SSL_accept
        BIO_get_mem_ptr(pSSLToNetBIO, &pSSLBuffer);
        assert(pSSLBuffer != NULL);
        assert(pSSLBuffer->length == 0);
        SSL_accept(pSSL);

        //the output BIO MUST contain some data at this point
        BIO_get_mem_ptr(pSSLToNetBIO, &pSSLBuffer);
        assert(pSSLBuffer != NULL);
        assert(pSSLBuffer->length != 0);

        //cleanup
        SSL_free(pSSL);
        SSL_CTX_free(pSslContext);
        X509_free(pX509);
        EVP_PKEY_free(pX509Key);
        CleanupSSL();

        return 0;
}

void InitSSL() {
        //init the random numbers generator
        int length = 16;
        int *pBuffer = (int *) malloc(length * sizeof (int));
        while (RAND_status() == 0) {
                for (int i = 0; i < length; i++) {
                        pBuffer[i] = rand();
                }

                RAND_seed(pBuffer, length * sizeof (int));
        }
        free(pBuffer);

        //init the SSL library
        SSL_library_init();

        //load SSL resources
        SSL_load_error_strings();
        ERR_load_SSL_strings();
        ERR_load_CRYPTO_strings();
        ERR_load_crypto_strings();
        OpenSSL_add_all_algorithms();
        OpenSSL_add_all_ciphers();
        OpenSSL_add_all_digests();
}

void CleanupSSL() {
        ERR_remove_state(0);
        ENGINE_cleanup();
        CONF_modules_unload(1);
        ERR_free_strings();
        EVP_cleanup();
        CRYPTO_cleanup_all_ex_data();
}

EVP_PKEY * CreateCertificateKey() {
        //create the keys container
        EVP_PKEY *pKey = EVP_PKEY_new();
        if (pKey == NULL)
                return NULL;

        //create the key itself which will be RSA
        RSA *pRSA = RSA_generate_key(
                        X509_KEY_SIZE, /* number of bits for the key - 2048 is 
a sensible value */
                        RSA_F4, /* exponent - RSA_F4 is defined as 0x10001L */
                        NULL, /* callback - can be NULL if we aren't displaying 
progress */
                        NULL /* callback argument - not needed in this case */
                        );
        if (pRSA == NULL) {
                EVP_PKEY_free(pKey);
                return NULL;
        }

        //assign the key to the keys container
        if (EVP_PKEY_assign_RSA(pKey, pRSA) != 1) {
                EVP_PKEY_free(pKey);
                RSA_free(pRSA);
                return NULL;
        }

        //done
        return pKey;
}

X509 * CreateCertificate(EVP_PKEY *pKey) {
        //see if we have a key
        if (pKey == NULL)
                return NULL;

        //create the certificate
        X509 *pX509 = X509_new();
        if (pX509 == NULL)
                return NULL;

        X509_NAME *pSubjectProperties = NULL;
        if (
                        //set the public key
                        (X509_set_pubkey(pX509, pKey) != 1)

                        //set the serial number
                        || (ASN1_INTEGER_set(X509_get_serialNumber(pX509), 1) 
!= 1)

                        //set validity period
                        || (X509_gmtime_adj(X509_get_notBefore(pX509), -1 * 24 
* 3600) == NULL)
                        || (X509_gmtime_adj(X509_get_notAfter(pX509), 
31536000L) == NULL)

                        //get the subject for the x509 cert
                        || ((pSubjectProperties = X509_get_subject_name(pX509)) 
== NULL)

                        //set the relevant properties on the subject
                        || (X509_NAME_add_entry_by_txt(pSubjectProperties, "C", 
MBSTRING_ASC, (unsigned char *) "CA", -1, -1, 0) != 1)
                        || (X509_NAME_add_entry_by_txt(pSubjectProperties, "O", 
MBSTRING_ASC, (unsigned char *) "Some org", -1, -1, 0) != 1)
                        || (X509_NAME_add_entry_by_txt(pSubjectProperties, 
"CN", MBSTRING_ASC, (unsigned char *) "example.com", -1, -1, 0) != 1)

                        //this will be self signed. So issuer == subject
                        || (X509_set_issuer_name(pX509, pSubjectProperties) != 
1)

                        //sign the certificate
                        || (X509_sign(pX509, pKey, EVP_sha1()) == 0)
                        ) {
                X509_free(pX509);
                return NULL;
        }

        //done
        return pX509;
}
> On Jan 14, 2015, at 22:08, Eugen-Andrei Gavriloaie <shir...@gmail.com> wrote:
> 
> Hi all,
> 
> I believe I have found a bug which is only present in the latest versions 
> (1.0.1k). I ran this test on a linux 64 ubuntu 14.10 and mac os x yosemite
> 
> I have created a simple C test which does the following things in this order:
> 
> 1. initialize the SSL library
> 2. creates an X509 key and cert
> 3. creates an DTLS server SSL context
> 4. Setup 2 memory BIO instances on the SSL context
> 5. Feed the input BIO with a hardcoded "Client Hello" packet
> 6. Call SSL_accept
> 
> Wanted:
> The output BIO should contain a packet ("Server Hello") to be sent over the 
> wire
> 
> Observed:
> The output BIO is empty, the handshake never succeeds
> 
> Same file test app linked with OpenSSL 1.0.1j works as expected, the output 
> is generated.
> 
> I have attached the C file.
> 
> Best regards,
> Andrei
> 
> <dtls_bug.c>
> 

_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

Reply via email to