Пример #1
0
void sender(char *key, int key_len, char *message)
  /*@ requires [_]public_invar(hmac_pub) &*&
               principal(?sender, _) &*&
               [?f1]cryptogram(key, key_len, ?key_cs, ?key_cg) &*&
                 key_cg == cg_symmetric_key(sender, ?id) &*&
               [?f2]chars(message, MESSAGE_SIZE, ?msg_cs) &*&
               true == send(sender, shared_with(sender, id), msg_cs); @*/
  /*@ ensures  principal(sender, _) &*&
               [f1]cryptogram(key, key_len, key_cs, key_cg) &*&
               [f2]chars(message, MESSAGE_SIZE, msg_cs); @*/
{
  //@ open principal(sender, _);
  int socket;
  char hmac[64];
  
  net_usleep(20000);
  if(net_connect(&socket, NULL, SERVER_PORT) != 0)
    abort();
  if(net_set_block(socket) != 0)
    abort();
  
  {
    int message_len = MESSAGE_SIZE + 64;
    char* M = malloc(message_len);
    if (M == 0) abort();
    
    //@ chars_to_crypto_chars(message, MESSAGE_SIZE);
    memcpy(M, message, MESSAGE_SIZE);
    sha512_hmac(key, (unsigned int) key_len, M, 
                (unsigned int) MESSAGE_SIZE, hmac, 0);
    //@ assert cryptogram(hmac, 64, ?hmac_cs, ?hmac_cg);
    //@ close hmac_pub(hmac_cg);
    //@ leak hmac_pub(hmac_cg);
    //@ public_cryptogram(hmac, hmac_cg);
    //@ chars_to_crypto_chars(hmac, 64);
    memcpy(M + MESSAGE_SIZE, hmac, 64);
    
    //@ crypto_chars_to_chars(M, MESSAGE_SIZE);
    //@ crypto_chars_to_chars(M + MESSAGE_SIZE, 64);
    //@ chars_join(M);
    net_send(&socket, M, (unsigned int) message_len);
    free(M);
  }
  net_close(socket);
  //@ close principal(sender, _);
}
Пример #2
0
void receiver(int sender, int receiver,
              char *s_pub_key, char *r_priv_key,
              char *s_nonce, char *r_nonce)
/*@ requires [_]public_invar(nsl_pub) &*&
             [_]decryption_key_classifier(nsl_public_key) &*&
             principal(receiver, _) &*&
             [?f1]cryptogram(s_pub_key, 8 * KEY_SIZE,
                             ?s_pub_key_ccs, ?s_pub_key_cg) &*&
               s_pub_key_cg == cg_public_key(sender, ?s_id) &*&
             [?f2]cryptogram(r_priv_key, 8 * KEY_SIZE,
                             ?r_priv_key_ccs, ?r_priv_key_cg) &*&
               r_priv_key_cg == cg_private_key(receiver, ?r_id) &*&
             chars(s_nonce, NONCE_SIZE, _) &*&
             chars(r_nonce, NONCE_SIZE, _); @*/
/*@ ensures  principal(receiver, _) &*&
             [f1]cryptogram(s_pub_key, 8 * KEY_SIZE,
                            s_pub_key_ccs, s_pub_key_cg) &*&
             [f2]cryptogram(r_priv_key, 8 * KEY_SIZE,
                            r_priv_key_ccs, r_priv_key_cg) &*&
             cryptogram(r_nonce, NONCE_SIZE, ?r_nonce_ccs, ?r_nonce_cg) &*&
               r_nonce_cg == cg_nonce(receiver, _) &*&
             (
               col || bad(sender) || bad(receiver) ?
                 chars(s_nonce, NONCE_SIZE, _)
               :
                 cryptogram(s_nonce, NONCE_SIZE, ?s_nonce_ccs, ?s_nonce_cg) &*&
                 s_nonce_cg == cg_nonce(sender, _) &*&
                 cg_info(s_nonce_cg) == int_pair(1, int_pair(receiver, r_id)) &*&
                 cg_info(r_nonce_cg) == int_pair(2, int_pair(sender, int_pair(sender,
                                                    int_pair(receiver, r_id))))
             ); @*/
{
  //@ open principal(receiver, _);
  int socket1;
  int socket2;
  pk_context s_context;
  pk_context r_context;
  havege_state havege_state;

  if(net_bind(&socket1, NULL, SERVER_PORT) != 0)
    abort();
  if(net_accept(socket1, &socket2, NULL) != 0)
    abort();
  if(net_set_block(socket2) != 0)
    abort();

  //@ close pk_context(&s_context);
  pk_init(&s_context);
  if (pk_parse_public_key(&s_context, s_pub_key,
                          (unsigned int) 8 * KEY_SIZE) != 0)
    abort();
  //@ close pk_context(&r_context);
  pk_init(&r_context);
  if (pk_parse_key(&r_context, r_priv_key,
                   (unsigned int) 8 * KEY_SIZE, NULL, 0) != 0)
    abort();

  // Generate NB
  //@ close havege_state(&havege_state);
  havege_init(&havege_state);

  //@ close principal(receiver, _);
  receiver_msg1(&socket2, &havege_state, &r_context, sender, receiver, s_nonce);
  //@ open principal(receiver, _);

  //@ assert receiver_inter(?p_orig, ?c_orig, ?p_inst, ?s_nonce_ccs, ?s_nonce_cg);
  //@ int info = int_pair(sender, int_pair(p_inst, int_pair(p_orig, c_orig)));
  //@ close random_request(receiver, int_pair(2, info), false);
  if (havege_random(&havege_state, r_nonce, NONCE_SIZE) != 0) abort();
  //@ close principal(receiver, _);
  receiver_msg2(&socket2, &havege_state, &s_context, receiver,
                s_nonce, r_nonce);
  //@ if (col || bad(p_inst) || bad(receiver)) chars_to_crypto_chars(s_nonce, NONCE_SIZE);
  //@ close receiver_inter(p_orig, c_orig, p_inst, s_nonce_ccs, s_nonce_cg);
  receiver_msg3(&socket2, &havege_state, &r_context, sender, receiver,
                s_nonce, r_nonce);
  /*@ if (col || bad(sender) || bad(receiver))
        crypto_chars_to_chars(s_nonce, NONCE_SIZE); @*/
  havege_free(&havege_state);
  //@ open havege_state(&havege_state);

  //@ pk_release_context_with_key(&s_context);
  pk_free(&s_context);
  //@ open pk_context(&s_context);
  //@ pk_release_context_with_key(&r_context);
  pk_free(&r_context);
  //@ open pk_context(&r_context);

  net_close(socket2);
  net_close(socket1);
}
Пример #3
0
void receiver(char *key, int key_len, char *message)
  /*@ requires [_]public_invar(hmac_pub) &*&
               principal(?receiver, _) &*&
               [?f1]cryptogram(key, key_len, ?key_cs, ?key_cg) &*&
                 key_cg == cg_symmetric_key(?sender, ?id) &*&
                 receiver == shared_with(sender, id) &*&
               chars(message, MESSAGE_SIZE, _); @*/
  /*@ ensures  principal(receiver, _) &*&
               [f1]cryptogram(key, key_len, key_cs, key_cg) &*&
               chars(message, MESSAGE_SIZE, ?msg_cs) &*&
               col || bad(sender) || bad(receiver) ||
               send(sender, receiver, msg_cs); @*/
{
  //@ open principal(receiver, _);
  int socket1;
  int socket2;
  
  if(net_bind(&socket1, NULL, SERVER_PORT) != 0)
    abort();
  if(net_accept(socket1, &socket2, NULL) != 0)
    abort();
  if(net_set_block(socket2) != 0)
    abort();
  
  {
    int size;
    char buffer[MAX_MESSAGE_SIZE];
    char hmac[64];
  
    size = net_recv(&socket2, buffer, MAX_MESSAGE_SIZE);
    int expected_size = MESSAGE_SIZE + 64;
    if (size != expected_size) abort();
    //@ chars_split(buffer, expected_size);
    //@ assert chars(buffer, MESSAGE_SIZE, ?msg_cs);
    /*@ close hide_chars((void*) buffer + expected_size, 
                         MAX_MESSAGE_SIZE - expected_size, _); @*/
    
    //Verify the hmac
    //@ chars_to_crypto_chars(buffer, MESSAGE_SIZE);
    sha512_hmac(key, (unsigned int) key_len, buffer, 
                (unsigned int) MESSAGE_SIZE, hmac, 0);
    memcpy(message, (void*) buffer , MESSAGE_SIZE);
    //@ open cryptogram(hmac, 64, ?hmac_cs, ?hmac_cg);
    //@ close memcmp_secret(hmac, 64, hmac_cs, hmac_cg);
    //@ assert hmac_cg == cg_hmac(sender, id, msg_cs);
    //@ assert chars((void*) buffer + MESSAGE_SIZE, 64, ?hmac_cs2);
    //@ public_chars((void*) buffer + MESSAGE_SIZE, 64);
    //@ chars_to_crypto_chars((void*) buffer + MESSAGE_SIZE, 64);
    if (memcmp((void*) buffer + MESSAGE_SIZE, hmac, 64) != 0) abort();
    //@ crypto_chars_join(buffer);
    //@ crypto_chars_to_chars(buffer, expected_size);
    //@ public_crypto_chars(hmac, 64);
    
    /*@ if (!col && !bad(sender) && !bad(receiver))
        {  
          public_chars_extract(hmac, hmac_cg);
          open [_]hmac_pub(hmac_cg);
          assert (send(sender, receiver, msg_cs) == true); 
        }
    @*/
    /*@ open hide_chars((void*) buffer + expected_size, 
                        MAX_MESSAGE_SIZE - expected_size, _); @*/
  }
  net_close(socket2);
  net_close(socket1);
  //@ close principal(receiver, _);
}
Пример #4
0
int main( int argc, char *argv[] )
{
    int ret = 0, len, server_fd, i, written, frags;
    unsigned char buf[SSL_MAX_CONTENT_LEN + 1];
#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
    unsigned char psk[POLARSSL_PSK_MAX_LEN];
    size_t psk_len = 0;
#endif
#if defined(POLARSSL_SSL_ALPN)
    const char *alpn_list[10];
#endif
    const char *pers = "ssl_client2";

    entropy_context entropy;
    ctr_drbg_context ctr_drbg;
    ssl_context ssl;
    ssl_session saved_session;
#if defined(POLARSSL_X509_CRT_PARSE_C)
    x509_crt cacert;
    x509_crt clicert;
    pk_context pkey;
#endif
    char *p, *q;
    const int *list;

    /*
     * Make sure memory references are valid.
     */
    server_fd = 0;
    memset( &ssl, 0, sizeof( ssl_context ) );
    memset( &saved_session, 0, sizeof( ssl_session ) );
#if defined(POLARSSL_X509_CRT_PARSE_C)
    x509_crt_init( &cacert );
    x509_crt_init( &clicert );
    pk_init( &pkey );
#endif
#if defined(POLARSSL_SSL_ALPN)
    memset( (void * ) alpn_list, 0, sizeof( alpn_list ) );
#endif

    if( argc == 0 )
    {
    usage:
        if( ret == 0 )
            ret = 1;

        printf( USAGE );

        list = ssl_list_ciphersuites();
        while( *list )
        {
            printf(" %-42s", ssl_get_ciphersuite_name( *list ) );
            list++;
            if( !*list )
                break;
            printf(" %s\n", ssl_get_ciphersuite_name( *list ) );
            list++;
        }
        printf("\n");
        goto exit;
    }

    opt.server_name         = DFL_SERVER_NAME;
    opt.server_addr         = DFL_SERVER_ADDR;
    opt.server_port         = DFL_SERVER_PORT;
    opt.debug_level         = DFL_DEBUG_LEVEL;
    opt.nbio                = DFL_NBIO;
    opt.request_page        = DFL_REQUEST_PAGE;
    opt.request_size        = DFL_REQUEST_SIZE;
    opt.ca_file             = DFL_CA_FILE;
    opt.ca_path             = DFL_CA_PATH;
    opt.crt_file            = DFL_CRT_FILE;
    opt.key_file            = DFL_KEY_FILE;
    opt.psk                 = DFL_PSK;
    opt.psk_identity        = DFL_PSK_IDENTITY;
    opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
    opt.renegotiation       = DFL_RENEGOTIATION;
    opt.allow_legacy        = DFL_ALLOW_LEGACY;
    opt.renegotiate         = DFL_RENEGOTIATE;
    opt.min_version         = DFL_MIN_VERSION;
    opt.max_version         = DFL_MAX_VERSION;
    opt.auth_mode           = DFL_AUTH_MODE;
    opt.mfl_code            = DFL_MFL_CODE;
    opt.trunc_hmac          = DFL_TRUNC_HMAC;
    opt.reconnect           = DFL_RECONNECT;
    opt.reco_delay          = DFL_RECO_DELAY;
    opt.tickets             = DFL_TICKETS;
    opt.alpn_string         = DFL_ALPN_STRING;

    for( i = 1; i < argc; i++ )
    {
        p = argv[i];
        if( ( q = strchr( p, '=' ) ) == NULL )
            goto usage;
        *q++ = '\0';

        if( strcmp( p, "server_name" ) == 0 )
            opt.server_name = q;
        else if( strcmp( p, "server_addr" ) == 0 )
            opt.server_addr = q;
        else if( strcmp( p, "server_port" ) == 0 )
        {
            opt.server_port = atoi( q );
            if( opt.server_port < 1 || opt.server_port > 65535 )
                goto usage;
        }
        else if( strcmp( p, "debug_level" ) == 0 )
        {
            opt.debug_level = atoi( q );
            if( opt.debug_level < 0 || opt.debug_level > 65535 )
                goto usage;
        }
        else if( strcmp( p, "nbio" ) == 0 )
        {
            opt.nbio = atoi( q );
            if( opt.nbio < 0 || opt.nbio > 2 )
                goto usage;
        }
        else if( strcmp( p, "request_page" ) == 0 )
            opt.request_page = q;
        else if( strcmp( p, "request_size" ) == 0 )
        {
            opt.request_size = atoi( q );
            if( opt.request_size < 0 || opt.request_size > SSL_MAX_CONTENT_LEN )
                goto usage;
        }
        else if( strcmp( p, "ca_file" ) == 0 )
            opt.ca_file = q;
        else if( strcmp( p, "ca_path" ) == 0 )
            opt.ca_path = q;
        else if( strcmp( p, "crt_file" ) == 0 )
            opt.crt_file = q;
        else if( strcmp( p, "key_file" ) == 0 )
            opt.key_file = q;
        else if( strcmp( p, "psk" ) == 0 )
            opt.psk = q;
        else if( strcmp( p, "psk_identity" ) == 0 )
            opt.psk_identity = q;
        else if( strcmp( p, "force_ciphersuite" ) == 0 )
        {
            opt.force_ciphersuite[0] = ssl_get_ciphersuite_id( q );

            if( opt.force_ciphersuite[0] == 0 )
            {
                ret = 2;
                goto usage;
            }
            opt.force_ciphersuite[1] = 0;
        }
        else if( strcmp( p, "renegotiation" ) == 0 )
        {
            opt.renegotiation = (atoi( q )) ? SSL_RENEGOTIATION_ENABLED :
                                              SSL_RENEGOTIATION_DISABLED;
        }
        else if( strcmp( p, "allow_legacy" ) == 0 )
        {
            opt.allow_legacy = atoi( q );
            if( opt.allow_legacy < 0 || opt.allow_legacy > 1 )
                goto usage;
        }
        else if( strcmp( p, "renegotiate" ) == 0 )
        {
            opt.renegotiate = atoi( q );
            if( opt.renegotiate < 0 || opt.renegotiate > 1 )
                goto usage;
        }
        else if( strcmp( p, "reconnect" ) == 0 )
        {
            opt.reconnect = atoi( q );
            if( opt.reconnect < 0 || opt.reconnect > 2 )
                goto usage;
        }
        else if( strcmp( p, "reco_delay" ) == 0 )
        {
            opt.reco_delay = atoi( q );
            if( opt.reco_delay < 0 )
                goto usage;
        }
        else if( strcmp( p, "tickets" ) == 0 )
        {
            opt.tickets = atoi( q );
            if( opt.tickets < 0 || opt.tickets > 2 )
                goto usage;
        }
        else if( strcmp( p, "alpn" ) == 0 )
        {
            opt.alpn_string = q;
        }
        else if( strcmp( p, "min_version" ) == 0 )
        {
            if( strcmp( q, "ssl3" ) == 0 )
                opt.min_version = SSL_MINOR_VERSION_0;
            else if( strcmp( q, "tls1" ) == 0 )
                opt.min_version = SSL_MINOR_VERSION_1;
            else if( strcmp( q, "tls1_1" ) == 0 )
                opt.min_version = SSL_MINOR_VERSION_2;
            else if( strcmp( q, "tls1_2" ) == 0 )
                opt.min_version = SSL_MINOR_VERSION_3;
            else
                goto usage;
        }
        else if( strcmp( p, "max_version" ) == 0 )
        {
            if( strcmp( q, "ssl3" ) == 0 )
                opt.max_version = SSL_MINOR_VERSION_0;
            else if( strcmp( q, "tls1" ) == 0 )
                opt.max_version = SSL_MINOR_VERSION_1;
            else if( strcmp( q, "tls1_1" ) == 0 )
                opt.max_version = SSL_MINOR_VERSION_2;
            else if( strcmp( q, "tls1_2" ) == 0 )
                opt.max_version = SSL_MINOR_VERSION_3;
            else
                goto usage;
        }
        else if( strcmp( p, "force_version" ) == 0 )
        {
            if( strcmp( q, "ssl3" ) == 0 )
            {
                opt.min_version = SSL_MINOR_VERSION_0;
                opt.max_version = SSL_MINOR_VERSION_0;
            }
            else if( strcmp( q, "tls1" ) == 0 )
            {
                opt.min_version = SSL_MINOR_VERSION_1;
                opt.max_version = SSL_MINOR_VERSION_1;
            }
            else if( strcmp( q, "tls1_1" ) == 0 )
            {
                opt.min_version = SSL_MINOR_VERSION_2;
                opt.max_version = SSL_MINOR_VERSION_2;
            }
            else if( strcmp( q, "tls1_2" ) == 0 )
            {
                opt.min_version = SSL_MINOR_VERSION_3;
                opt.max_version = SSL_MINOR_VERSION_3;
            }
            else
                goto usage;
        }
        else if( strcmp( p, "auth_mode" ) == 0 )
        {
            if( strcmp( q, "none" ) == 0 )
                opt.auth_mode = SSL_VERIFY_NONE;
            else if( strcmp( q, "optional" ) == 0 )
                opt.auth_mode = SSL_VERIFY_OPTIONAL;
            else if( strcmp( q, "required" ) == 0 )
                opt.auth_mode = SSL_VERIFY_REQUIRED;
            else
                goto usage;
        }
        else if( strcmp( p, "max_frag_len" ) == 0 )
        {
            if( strcmp( q, "512" ) == 0 )
                opt.mfl_code = SSL_MAX_FRAG_LEN_512;
            else if( strcmp( q, "1024" ) == 0 )
                opt.mfl_code = SSL_MAX_FRAG_LEN_1024;
            else if( strcmp( q, "2048" ) == 0 )
                opt.mfl_code = SSL_MAX_FRAG_LEN_2048;
            else if( strcmp( q, "4096" ) == 0 )
                opt.mfl_code = SSL_MAX_FRAG_LEN_4096;
            else
                goto usage;
        }
        else if( strcmp( p, "trunc_hmac" ) == 0 )
        {
            opt.trunc_hmac = atoi( q );
            if( opt.trunc_hmac < 0 || opt.trunc_hmac > 1 )
                goto usage;
        }
        else
            goto usage;
    }

#if defined(POLARSSL_DEBUG_C)
    debug_set_threshold( opt.debug_level );
#endif

    if( opt.force_ciphersuite[0] > 0 )
    {
        const ssl_ciphersuite_t *ciphersuite_info;
        ciphersuite_info = ssl_ciphersuite_from_id( opt.force_ciphersuite[0] );

        if( opt.max_version != -1 &&
            ciphersuite_info->min_minor_ver > opt.max_version )
        {
            printf("forced ciphersuite not allowed with this protocol version\n");
            ret = 2;
            goto usage;
        }
        if( opt.min_version != -1 &&
            ciphersuite_info->max_minor_ver < opt.min_version )
        {
            printf("forced ciphersuite not allowed with this protocol version\n");
            ret = 2;
            goto usage;
        }
        if( opt.max_version > ciphersuite_info->max_minor_ver )
            opt.max_version = ciphersuite_info->max_minor_ver;
        if( opt.min_version < ciphersuite_info->min_minor_ver )
            opt.min_version = ciphersuite_info->min_minor_ver;
    }

#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
    /*
     * Unhexify the pre-shared key if any is given
     */
    if( strlen( opt.psk ) )
    {
        unsigned char c;
        size_t j;

        if( strlen( opt.psk ) % 2 != 0 )
        {
            printf("pre-shared key not valid hex\n");
            goto exit;
        }

        psk_len = strlen( opt.psk ) / 2;

        for( j = 0; j < strlen( opt.psk ); j += 2 )
        {
            c = opt.psk[j];
            if( c >= '0' && c <= '9' )
                c -= '0';
            else if( c >= 'a' && c <= 'f' )
                c -= 'a' - 10;
            else if( c >= 'A' && c <= 'F' )
                c -= 'A' - 10;
            else
            {
                printf("pre-shared key not valid hex\n");
                goto exit;
            }
            psk[ j / 2 ] = c << 4;

            c = opt.psk[j + 1];
            if( c >= '0' && c <= '9' )
                c -= '0';
            else if( c >= 'a' && c <= 'f' )
                c -= 'a' - 10;
            else if( c >= 'A' && c <= 'F' )
                c -= 'A' - 10;
            else
            {
                printf("pre-shared key not valid hex\n");
                goto exit;
            }
            psk[ j / 2 ] |= c;
        }
    }
#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */

#if defined(POLARSSL_SSL_ALPN)
    if( opt.alpn_string != NULL )
    {
        p = (char *) opt.alpn_string;
        i = 0;

        /* Leave room for a final NULL in alpn_list */
        while( i < (int) sizeof alpn_list - 1 && *p != '\0' )
        {
            alpn_list[i++] = p;

            /* Terminate the current string and move on to next one */
            while( *p != ',' && *p != '\0' )
                p++;
            if( *p == ',' )
                *p++ = '\0';
        }
    }
#endif /* POLARSSL_SSL_ALPN */

    /*
     * 0. Initialize the RNG and the session data
     */
    printf( "\n  . Seeding the random number generator..." );
    fflush( stdout );

    entropy_init( &entropy );
    if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
                               (const unsigned char *) pers,
                               strlen( pers ) ) ) != 0 )
    {
        printf( " failed\n  ! ctr_drbg_init returned -0x%x\n", -ret );
        goto exit;
    }

    printf( " ok\n" );

#if defined(POLARSSL_X509_CRT_PARSE_C)
    /*
     * 1.1. Load the trusted CA
     */
    printf( "  . Loading the CA root certificate ..." );
    fflush( stdout );

#if defined(POLARSSL_FS_IO)
    if( strlen( opt.ca_path ) )
        if( strcmp( opt.ca_path, "none" ) == 0 )
            ret = 0;
        else
            ret = x509_crt_parse_path( &cacert, opt.ca_path );
    else if( strlen( opt.ca_file ) )
        if( strcmp( opt.ca_file, "none" ) == 0 )
            ret = 0;
        else
            ret = x509_crt_parse_file( &cacert, opt.ca_file );
    else
#endif
#if defined(POLARSSL_CERTS_C)
        ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_list,
                strlen( test_ca_list ) );
#else
    {
        ret = 1;
        printf("POLARSSL_CERTS_C not defined.");
    }
#endif
    if( ret < 0 )
    {
        printf( " failed\n  !  x509_crt_parse returned -0x%x\n\n", -ret );
        goto exit;
    }

    printf( " ok (%d skipped)\n", ret );

    /*
     * 1.2. Load own certificate and private key
     *
     * (can be skipped if client authentication is not required)
     */
    printf( "  . Loading the client cert. and key..." );
    fflush( stdout );

#if defined(POLARSSL_FS_IO)
    if( strlen( opt.crt_file ) )
        if( strcmp( opt.crt_file, "none" ) == 0 )
            ret = 0;
        else
            ret = x509_crt_parse_file( &clicert, opt.crt_file );
    else
#endif
#if defined(POLARSSL_CERTS_C)
        ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt,
                strlen( test_cli_crt ) );
#else
    {
        ret = 1;
        printf("POLARSSL_CERTS_C not defined.");
    }
#endif
    if( ret != 0 )
    {
        printf( " failed\n  !  x509_crt_parse returned -0x%x\n\n", -ret );
        goto exit;
    }

#if defined(POLARSSL_FS_IO)
    if( strlen( opt.key_file ) )
        if( strcmp( opt.key_file, "none" ) == 0 )
            ret = 0;
        else
            ret = pk_parse_keyfile( &pkey, opt.key_file, "" );
    else
#endif
#if defined(POLARSSL_CERTS_C)
        ret = pk_parse_key( &pkey, (const unsigned char *) test_cli_key,
                strlen( test_cli_key ), NULL, 0 );
#else
    {
        ret = 1;
        printf("POLARSSL_CERTS_C not defined.");
    }
#endif
    if( ret != 0 )
    {
        printf( " failed\n  !  pk_parse_key returned -0x%x\n\n", -ret );
        goto exit;
    }

    printf( " ok\n" );
#endif /* POLARSSL_X509_CRT_PARSE_C */

    /*
     * 2. Start the connection
     */
    if( opt.server_addr == NULL)
        opt.server_addr = opt.server_name;

    printf( "  . Connecting to tcp/%s/%-4d...", opt.server_addr,
                                                opt.server_port );
    fflush( stdout );

    if( ( ret = net_connect( &server_fd, opt.server_addr,
                                         opt.server_port ) ) != 0 )
    {
        printf( " failed\n  ! net_connect returned -0x%x\n\n", -ret );
        goto exit;
    }

    if( opt.nbio > 0 )
        ret = net_set_nonblock( server_fd );
    else
        ret = net_set_block( server_fd );
    if( ret != 0 )
    {
        printf( " failed\n  ! net_set_(non)block() returned -0x%x\n\n", -ret );
        goto exit;
    }

    printf( " ok\n" );

    /*
     * 3. Setup stuff
     */
    printf( "  . Setting up the SSL/TLS structure..." );
    fflush( stdout );

    if( ( ret = ssl_init( &ssl ) ) != 0 )
    {
        printf( " failed\n  ! ssl_init returned -0x%x\n\n", -ret );
        goto exit;
    }

    printf( " ok\n" );

#if defined(POLARSSL_X509_CRT_PARSE_C)
    if( opt.debug_level > 0 )
        ssl_set_verify( &ssl, my_verify, NULL );
#endif

    ssl_set_endpoint( &ssl, SSL_IS_CLIENT );
    ssl_set_authmode( &ssl, opt.auth_mode );

#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
    if( ( ret = ssl_set_max_frag_len( &ssl, opt.mfl_code ) ) != 0 )
    {
        printf( " failed\n  ! ssl_set_max_frag_len returned %d\n\n", ret );
        goto exit;
    }
#endif

#if defined(POLARSSL_SSL_TRUNCATED_HMAC)
    if( opt.trunc_hmac != 0 )
        if( ( ret = ssl_set_truncated_hmac( &ssl, SSL_TRUNC_HMAC_ENABLED ) ) != 0 )
        {
            printf( " failed\n  ! ssl_set_truncated_hmac returned %d\n\n", ret );
            goto exit;
        }
#endif

#if defined(POLARSSL_SSL_ALPN)
    if( opt.alpn_string != NULL )
        if( ( ret = ssl_set_alpn_protocols( &ssl, alpn_list ) ) != 0 )
        {
            printf( " failed\n  ! ssl_set_alpn_protocols returned %d\n\n", ret );
            goto exit;
        }
#endif

    ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg );
    ssl_set_dbg( &ssl, my_debug, stdout );

    if( opt.nbio == 2 )
        ssl_set_bio( &ssl, my_recv, &server_fd, my_send, &server_fd );
    else
        ssl_set_bio( &ssl, net_recv, &server_fd, net_send, &server_fd );

#if defined(POLARSSL_SSL_SESSION_TICKETS)
    if( ( ret = ssl_set_session_tickets( &ssl, opt.tickets ) ) != 0 )
    {
        printf( " failed\n  ! ssl_set_session_tickets returned %d\n\n", ret );
        goto exit;
    }
#endif

    if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER )
        ssl_set_ciphersuites( &ssl, opt.force_ciphersuite );

    ssl_set_renegotiation( &ssl, opt.renegotiation );
    ssl_legacy_renegotiation( &ssl, opt.allow_legacy );

#if defined(POLARSSL_X509_CRT_PARSE_C)
    if( strcmp( opt.ca_path, "none" ) != 0 &&
        strcmp( opt.ca_file, "none" ) != 0 )
    {
        ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name );
    }
    if( strcmp( opt.crt_file, "none" ) != 0 &&
        strcmp( opt.key_file, "none" ) != 0 )
    {
        if( ( ret = ssl_set_own_cert( &ssl, &clicert, &pkey ) ) != 0 )
        {
            printf( " failed\n  ! ssl_set_own_cert returned %d\n\n", ret );
            goto exit;
        }
    }
#endif

#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
    if( ( ret = ssl_set_psk( &ssl, psk, psk_len,
                             (const unsigned char *) opt.psk_identity,
                             strlen( opt.psk_identity ) ) ) != 0 )
    {
        printf( " failed\n  ! ssl_set_psk returned %d\n\n", ret );
        goto exit;
    }
#endif

#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
    if( ( ret = ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
    {
        printf( " failed\n  ! ssl_set_hostname returned %d\n\n", ret );
        goto exit;
    }
#endif

    if( opt.min_version != -1 )
        ssl_set_min_version( &ssl, SSL_MAJOR_VERSION_3, opt.min_version );
    if( opt.max_version != -1 )
        ssl_set_max_version( &ssl, SSL_MAJOR_VERSION_3, opt.max_version );

    /*
     * 4. Handshake
     */
    printf( "  . Performing the SSL/TLS handshake..." );
    fflush( stdout );

    while( ( ret = ssl_handshake( &ssl ) ) != 0 )
    {
        if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
        {
            printf( " failed\n  ! ssl_handshake returned -0x%x\n", -ret );
            if( ret == POLARSSL_ERR_X509_CERT_VERIFY_FAILED )
                printf(
                    "    Unable to verify the server's certificate. "
                        "Either it is invalid,\n"
                    "    or you didn't set ca_file or ca_path "
                        "to an appropriate value.\n"
                    "    Alternatively, you may want to use "
                        "auth_mode=optional for testing purposes.\n" );
            printf( "\n" );
            goto exit;
        }
    }

    printf( " ok\n    [ Protocol is %s ]\n    [ Ciphersuite is %s ]\n",
            ssl_get_version( &ssl ), ssl_get_ciphersuite( &ssl ) );

#if defined(POLARSSL_SSL_ALPN)
    if( opt.alpn_string != NULL )
    {
        const char *alp = ssl_get_alpn_protocol( &ssl );
        printf( "    [ Application Layer Protocol is %s ]\n",
                alp ? alp : "(none)" );
    }
#endif

    if( opt.reconnect != 0 )
    {
        printf("  . Saving session for reuse..." );
        fflush( stdout );

        if( ( ret = ssl_get_session( &ssl, &saved_session ) ) != 0 )
        {
            printf( " failed\n  ! ssl_get_session returned -0x%x\n\n", -ret );
            goto exit;
        }

        printf( " ok\n" );
    }

#if defined(POLARSSL_X509_CRT_PARSE_C)
    /*
     * 5. Verify the server certificate
     */
    printf( "  . Verifying peer X.509 certificate..." );

    if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 )
    {
        printf( " failed\n" );

        if( ( ret & BADCERT_EXPIRED ) != 0 )
            printf( "  ! server certificate has expired\n" );

        if( ( ret & BADCERT_REVOKED ) != 0 )
            printf( "  ! server certificate has been revoked\n" );

        if( ( ret & BADCERT_CN_MISMATCH ) != 0 )
            printf( "  ! CN mismatch (expected CN=%s)\n", opt.server_name );

        if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
            printf( "  ! self-signed or not signed by a trusted CA\n" );

        printf( "\n" );
    }
    else
        printf( " ok\n" );

    if( ssl_get_peer_cert( &ssl ) != NULL )
    {
        printf( "  . Peer certificate information    ...\n" );
        x509_crt_info( (char *) buf, sizeof( buf ) - 1, "      ",
                       ssl_get_peer_cert( &ssl ) );
        printf( "%s\n", buf );
    }
#endif /* POLARSSL_X509_CRT_PARSE_C */

    if( opt.renegotiate )
    {
        /*
         * Perform renegotiation (this must be done when the server is waiting
         * for input from our side).
         */
        printf( "  . Performing renegotiation..." );
        fflush( stdout );
        while( ( ret = ssl_renegotiate( &ssl ) ) != 0 )
        {
            if( ret != POLARSSL_ERR_NET_WANT_READ &&
                ret != POLARSSL_ERR_NET_WANT_WRITE )
            {
                printf( " failed\n  ! ssl_renegotiate returned %d\n\n", ret );
                goto exit;
            }
        }
        printf( " ok\n" );
    }

    /*
     * 6. Write the GET request
     */
send_request:
    printf( "  > Write to server:" );
    fflush( stdout );

    if( strcmp( opt.request_page, "SERVERQUIT" ) == 0 )
        len = sprintf( (char *) buf, "%s", opt.request_page );
    else
    {
        size_t tail_len = strlen( GET_REQUEST_END );

        len = snprintf( (char *) buf, sizeof(buf) - 1, GET_REQUEST,
                        opt.request_page );

        /* Add padding to GET request to reach opt.request_size in length */
        if( opt.request_size != DFL_REQUEST_SIZE &&
            len + tail_len < (size_t) opt.request_size )
        {
            memset( buf + len, 'A', opt.request_size - len - tail_len );
            len += opt.request_size - len - tail_len;
        }

        strncpy( (char *) buf + len, GET_REQUEST_END, sizeof(buf) - len - 1 );
        len += tail_len;
    }

    /* Truncate if request size is smaller than the "natural" size */
    if( opt.request_size != DFL_REQUEST_SIZE &&
        len > opt.request_size )
    {
        len = opt.request_size;

        /* Still end with \r\n unless that's really not possible */
        if( len >= 2 ) buf[len - 2] = '\r';
        if( len >= 1 ) buf[len - 1] = '\n';
    }

    for( written = 0, frags = 0; written < len; written += ret, frags++ )
    {
        while( ( ret = ssl_write( &ssl, buf + written, len - written ) ) <= 0 )
        {
            if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
            {
                printf( " failed\n  ! ssl_write returned -0x%x\n\n", -ret );
                goto exit;
            }
        }
    }

    buf[written] = '\0';
    printf( " %d bytes written in %d fragments\n\n%s\n", written, frags, (char *) buf );

    /*
     * 7. Read the HTTP response
     */
    printf( "  < Read from server:" );
    fflush( stdout );

    do
    {
        len = sizeof( buf ) - 1;
        memset( buf, 0, sizeof( buf ) );
        ret = ssl_read( &ssl, buf, len );

        if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE )
            continue;

        if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY )
            break;

        if( ret < 0 )
        {
            printf( "failed\n  ! ssl_read returned -0x%x\n\n", -ret );
            break;
        }

        if( ret == 0 )
        {
            printf("\n\nEOF\n\n");
            ssl_close_notify( &ssl );
            break;
        }

        len = ret;
        buf[len] = '\0';
        printf( " %d bytes read\n\n%s", len, (char *) buf );
    }
    while( 1 );

    if( opt.reconnect != 0 )
    {
        --opt.reconnect;

        net_close( server_fd );

#if defined(POLARSSL_TIMING_C)
        if( opt.reco_delay > 0 )
            m_sleep( 1000 * opt.reco_delay );
#endif

        printf( "  . Reconnecting with saved session..." );
        fflush( stdout );

        if( ( ret = ssl_session_reset( &ssl ) ) != 0 )
        {
            printf( " failed\n  ! ssl_session_reset returned -0x%x\n\n", -ret );
            goto exit;
        }

        if( ( ret = ssl_set_session( &ssl, &saved_session ) ) != 0 )
        {
            printf( " failed\n  ! ssl_set_session returned %d\n\n", ret );
            goto exit;
        }

        if( ( ret = net_connect( &server_fd, opt.server_name,
                        opt.server_port ) ) != 0 )
        {
            printf( " failed\n  ! net_connect returned -0x%x\n\n", -ret );
            goto exit;
        }

        while( ( ret = ssl_handshake( &ssl ) ) != 0 )
        {
            if( ret != POLARSSL_ERR_NET_WANT_READ &&
                ret != POLARSSL_ERR_NET_WANT_WRITE )
            {
                printf( " failed\n  ! ssl_handshake returned -0x%x\n\n", -ret );
                goto exit;
            }
        }

        printf( " ok\n" );

        goto send_request;
    }

exit:
    if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY )
        ret = 0;

#ifdef POLARSSL_ERROR_C
    if( ret != 0 )
    {
        char error_buf[100];
        polarssl_strerror( ret, error_buf, 100 );
        printf("Last error was: -0x%X - %s\n\n", -ret, error_buf );
    }
#endif

    if( server_fd )
        net_close( server_fd );
#if defined(POLARSSL_X509_CRT_PARSE_C)
    x509_crt_free( &clicert );
    x509_crt_free( &cacert );
    pk_free( &pkey );
#endif
    ssl_session_free( &saved_session );
    ssl_free( &ssl );
    ctr_drbg_free( &ctr_drbg );
    entropy_free( &entropy );

    memset( &ssl, 0, sizeof( ssl ) );

#if defined(_WIN32)
    printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    // Shell can not handle large exit numbers -> 1 for errors
    if( ret < 0 )
        ret = 1;

    return( ret );
}
Пример #5
0
void sender(int sender, int receiver,
            char *s_priv_key, char *r_pub_key,
            char *s_nonce, char *r_nonce)
/*@ requires [_]public_invar(nsl_pub) &*&
             [_]decryption_key_classifier(nsl_public_key) &*&
             principal(sender, _) &*&
             [?f1]cryptogram(s_priv_key, 8 * KEY_SIZE,
                             ?s_priv_key_ccs, ?s_priv_key_cg) &*&
               s_priv_key_cg == cg_private_key(sender, ?s_id) &*&
             [?f2]cryptogram(r_pub_key, 8 * KEY_SIZE,
                             ?r_pub_key_ccs, ?r_pub_key_cg) &*&
               r_pub_key_cg == cg_public_key(receiver, ?r_id) &*&
             chars(s_nonce, NONCE_SIZE, _) &*&
             chars(r_nonce, NONCE_SIZE, _); @*/
/*@ ensures  principal(sender, _) &*&
             [f1]cryptogram(s_priv_key, 8 * KEY_SIZE,
                            s_priv_key_ccs, s_priv_key_cg) &*&
             [f2]cryptogram(r_pub_key, 8 * KEY_SIZE,
                            r_pub_key_ccs, r_pub_key_cg) &*&
             cryptogram(s_nonce, NONCE_SIZE, ?s_nonce_ccs, ?s_nonce_cg) &*&
               s_nonce_cg == cg_nonce(sender, _) &*&
               cg_info(s_nonce_cg) == int_pair(1, int_pair(receiver, r_id)) &*&
             col || bad(sender) || bad(receiver) ?
               chars(r_nonce, NONCE_SIZE, _)
             :
               cryptogram(r_nonce, NONCE_SIZE, _, ?r_nonce_cg) &*&
               r_nonce_cg == cg_nonce(receiver, _) &*&
               cg_info(r_nonce_cg) == int_pair(2, int_pair(sender, int_pair(sender,
                                                  int_pair(receiver, r_id)))); @*/
{
  int socket;
  pk_context s_context;
  pk_context r_context;
  havege_state havege_state;

  net_usleep(20000);
  if(net_connect(&socket, NULL, SERVER_PORT) != 0)
    abort();
  if(net_set_block(socket) != 0)
    abort();

  //@ close pk_context(&s_context);
  pk_init(&s_context);
  if (pk_parse_key(&s_context, s_priv_key,
                   (unsigned int) 8 * KEY_SIZE, NULL, 0) != 0)
    abort();
  //@ close pk_context(&r_context);
  pk_init(&r_context);
  if (pk_parse_public_key(&r_context, r_pub_key,
                          (unsigned int) 8 * KEY_SIZE) != 0)
    abort();

  // Generate NA
  //@ open principal(sender, _);
  //@ close havege_state(&havege_state);
  havege_init(&havege_state);
  //@ close random_request(sender, int_pair(1, int_pair(receiver, r_id)), false);
  if (havege_random(&havege_state, s_nonce, NONCE_SIZE) != 0) abort();
  //@ assert cryptogram(s_nonce, NONCE_SIZE, ?cs_s_nonce, ?cg_s_nonce);
  //@ close principal(sender, _);

  sender_msg1(&socket, &havege_state, &r_context, sender, s_nonce);
  sender_msg2(&socket, &havege_state, &s_context, sender, receiver,
              s_nonce, r_nonce);
  sender_msg3(&socket, &havege_state, &r_context, sender, r_nonce);
  havege_free(&havege_state);
  //@ open havege_state(&havege_state);

  //@ pk_release_context_with_key(&s_context);
  pk_free(&s_context);
  //@ open pk_context(&s_context);
  //@ pk_release_context_with_key(&r_context);
  pk_free(&r_context);
  //@ open pk_context(&r_context);

  net_close(socket);
}
void app_send(char *key, char *message, int message_len)
  /*@ requires polarssl_generated_values(?creator, ?count1) &*&
               [?f0]polarssl_world(sc_auth_polarssl_pub) &*&
               [?f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, ?key_cs, ?key_cg) &*&
                 key_cg == polarssl_symmetric_key(creator, ?key_id) &*&
               [?f2]chars(message, message_len, ?m_cs) &*&
                 message_len >= POLARSSL_MIN_ENCRYPTED_BYTE_SIZE &*&
                 message_len < POLARSSL_MAX_MESSAGE_BYTE_SIZE - 84 &*&
                 bad(creator) ?
                   [_]polarssl_public_generated_chars(sc_auth_polarssl_pub)(m_cs)
                 :
                   true == app_send_event(creator, m_cs);
  @*/
  /*@ ensures  polarssl_generated_values(creator, ?count2) &*& count2 > count1 &*&
               [f0]polarssl_world(sc_auth_polarssl_pub) &*&
               [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg) &*&
               [f2]chars(message, message_len, m_cs);
  @*/
{
  int socket;
  havege_state havege_state;
  char iv[16];

  // init
  {
    net_usleep(20000);
    if(net_connect(&socket, NULL, APP_RECEIVE_PORT) != 0)
      abort();
    if(net_set_block(socket) != 0)
      abort();

    //@ close havege_state(&havege_state);
    havege_init(&havege_state);
  }

  // iv stuff
  {
    //@ close random_request(creator, 0, false);
    if (havege_random(&havege_state, iv, 16) != 0) abort();  
  }
  //@ open polarssl_cryptogram(iv, 16, ?iv_cs, _);

  char* m = malloc(16 + message_len + 16);
  if (m == 0) abort();
  memcpy(m, iv, 16);
  //@ assert chars(m, 16, iv_cs);
  //@ assert chars(m + 16, message_len + 16, ?cs1);
  //@ polarssl_public_generated_chars_assume(sc_auth_polarssl_pub, iv_cs);
   
  // encrypt message
  {
    unsigned int temp;
    gcm_context gcm_context;
    //@ close gcm_context(&gcm_context);
    //@ open [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg);
    //@ close polarssl_key_id(creator, key_id);
    if (gcm_init(&gcm_context, POLARSSL_AES_CIPHER_ID, key, 
                (unsigned int) KEY_BYTE_SIZE * 8) != 0) abort();
    //@ close [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg);
    //@ chars_split(m + 16, message_len);
    if (gcm_crypt_and_tag(&gcm_context, POLARSSL_GCM_ENCRYPT, 
                          (unsigned int) message_len,
                          iv, 16, NULL, 0, message, m + 16, 16,
                          (char*) ((m + 16) + message_len)) != 0)
      abort();
    gcm_free(&gcm_context);
    //@ open gcm_context(&gcm_context);
  }
  //@ assert polarssl_cryptogram(m + 16, message_len, ?e_cs, ?e_cg);
  /*@ assert e_cg == polarssl_auth_encrypted(
                                       creator, key_id, ?t_cs, m_cs, iv_cs); @*/
  //@ close sc_auth_polarssl_pub(e_cg);
  //@ leak sc_auth_polarssl_pub(e_cg);
  /*@ polarssl_public_message_from_cryptogram(
                     sc_auth_polarssl_pub, m + 16, message_len, e_cs, e_cg); @*/
  /*@ open polarssl_public_message(sc_auth_polarssl_pub)
                                  (m + 16, message_len, e_cs); @*/
  //@ assert chars(m + 16 + message_len, 16, t_cs);
  //@ chars_join(m);
  //@ chars_join(m);
  //@ assert chars(m, 16 + message_len + 16, ?cs);
  //@ append_assoc(iv_cs, e_cs, t_cs);
  //@ assert cs == append(iv_cs, append(e_cs, t_cs));
  
  //@ polarssl_public_generated_chars_assume(sc_auth_polarssl_pub, t_cs);
  /*@ polarssl_public_generated_chars_join(
                                         sc_auth_polarssl_pub, iv_cs, e_cs); @*/
  /*@ polarssl_public_generated_chars_join(
                           sc_auth_polarssl_pub, append(iv_cs, e_cs), t_cs); @*/
  /*@ close polarssl_public_message(sc_auth_polarssl_pub)
                                   (m, 16 + message_len + 16,
                                    append(iv_cs, append(e_cs, t_cs))); @*/
  net_send(&socket, m, (unsigned int) 16 + (unsigned int) message_len + 16);
  //@ open polarssl_public_message(sc_auth_polarssl_pub)(m, _, _);

  {
    free(m);
    havege_free(&havege_state);
    //@ open havege_state(&havege_state);
    net_close(socket);
  }
}
int app_receive(char *key, char **message)
  /*@ requires [?f0]polarssl_world(sc_auth_polarssl_pub) &*&
               [?f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, ?key_cs, ?key_cg) &*&
                 key_cg == polarssl_symmetric_key(?creator, ?key_id) &*&
               pointer(message, _);
  @*/
  /*@ ensures  [f0]polarssl_world(sc_auth_polarssl_pub) &*&
               [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg) &*&
               pointer(message, ?message_p) &*&
               malloc_block(message_p, result) &*&
               chars(message_p, result, ?m_cs) &*&
               bad(creator) ?
                 [_]polarssl_public_generated_chars(sc_auth_polarssl_pub)(m_cs)
               : 
                 true == app_send_event(creator, m_cs);
  @*/
{
  int socket1;
  int socket2;
  int size;
  int result_size;
  char buffer[POLARSSL_MAX_MESSAGE_BYTE_SIZE];

  char iv[16];
  char tag[16];
  char* encrypted;
  char* decrypted;

  // Receive message
  if(net_bind(&socket1, NULL, APP_RECEIVE_PORT) != 0)
    abort();
  if(net_accept(socket1, &socket2, NULL) != 0)
    abort();
  if(net_set_block(socket2) != 0)
    abort();
    
  size = net_recv(&socket2, buffer, POLARSSL_MAX_MESSAGE_BYTE_SIZE);
  if (size < 16 + POLARSSL_MIN_ENCRYPTED_BYTE_SIZE + 16)
    abort();
  //@ open polarssl_public_message(sc_auth_polarssl_pub)(buffer, size, ?cs);
  //@ close [1/2]hide_chars(buffer, size, cs);
  result_size = size - 16 - 16;
  encrypted = malloc(result_size);
  if (encrypted == 0) abort();
  decrypted = malloc(result_size);
  if (decrypted == 0) abort();
  
  // Extract parts of message
  memcpy(iv, buffer, 16);
  memcpy(encrypted, (void*) buffer + 16, (unsigned int) result_size);
  memcpy(tag, (void*) buffer + 16 + result_size, 16);
  //@ assert chars(iv, 16, ?iv_cs);
  //@ assert chars(encrypted, result_size, ?e_cs);
  //@ assert chars(tag, 16, ?t_cs);
  //@ chars_join(buffer);
  //@ chars_join(buffer);
  //@ open [1/2]hide_chars(buffer, size, cs);
  //@ close [1/2]hide_chars(buffer, size, cs);
  //@ assert cs == append(iv_cs, append(e_cs, t_cs));

  // Decrypt message
  {
    gcm_context gcm_context;
    //@ close gcm_context(&gcm_context);
    //@ open [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg);
    //@ close polarssl_key_id(creator, key_id);
    if (gcm_init(&gcm_context, POLARSSL_AES_CIPHER_ID, key, 
                (unsigned int) KEY_BYTE_SIZE * 8) != 0) abort();
    /*@ assert gcm_context_initialized(&gcm_context, 
                                       some(pair(creator, key_id))); @*/
    //@ close [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg);

    //@ polarssl_public_generated_chars_split(sc_auth_polarssl_pub, cs, 16);
    /*@ polarssl_public_generated_chars_split(
                     sc_auth_polarssl_pub, append(e_cs, t_cs), result_size); @*/
    //@ assert chars(encrypted, result_size, e_cs);
    if (gcm_auth_decrypt(&gcm_context, (unsigned int) result_size,
                         iv, 16, NULL, 0, tag, 16,
                         encrypted, decrypted) != 0) abort();
    gcm_free(&gcm_context);
    //@ open gcm_context(&gcm_context);
  }
  
  //@ assert chars(decrypted, result_size, ?dec_cs);
  //@ chars_join(buffer);
  //@ open [1/2]hide_chars(buffer, size, cs);

  /*@ polarssl_cryptogram e_cg = polarssl_auth_encrypted(
                                      creator, key_id, t_cs, dec_cs, iv_cs); @*/
  //@ assert e_cs == polarssl_chars_for_cryptogram(e_cg);
  //@ polarssl_cryptogram_constraints(e_cs, e_cg);
  /*@ polarssl_public_generated_chars_extract(
                                          sc_auth_polarssl_pub, e_cs, e_cg); @*/
  //@ open [_]sc_auth_polarssl_pub(e_cg);
  /*@ if (!bad(creator))
      {
        assert true == app_send_event(creator, dec_cs);
      }
      else
      {
        assert [_]polarssl_public_generated_chars(sc_auth_polarssl_pub)(dec_cs);
      }
  @*/

  net_close(socket1);
  net_close(socket2);
  
  free(encrypted);
  *message = decrypted;
  return result_size;
}
Пример #8
0
void sender(char *enc_key, char *hmac_key, char *msg, unsigned int msg_len)
/*@ requires [_]public_invar(enc_then_hmac_pub) &*&
             principal(?sender, _) &*&
             [?f1]cryptogram(enc_key, KEY_SIZE, ?enc_key_ccs, ?enc_key_cg) &*&
             [?f2]cryptogram(hmac_key, KEY_SIZE, ?hmac_key_ccs, ?hmac_key_cg) &*&
               enc_key_cg == cg_symmetric_key(sender, ?enc_id) &*&
               hmac_key_cg == cg_symmetric_key(sender, ?hmac_id) &*&
                 cg_info(hmac_key_cg) == enc_id &*&
               shared_with(sender, enc_id) == shared_with(sender, hmac_id) &*&
             [?f3]crypto_chars(secret, msg, msg_len, ?msg_ccs) &*&
               MAX_SIZE >= msg_len &*& msg_len >= MINIMAL_STRING_SIZE &*&
               bad(sender) || bad(shared_with(sender, enc_id)) ?
                 [_]public_ccs(msg_ccs)
               :
                 true == send(sender, shared_with(sender, enc_id), msg_ccs); @*/
/*@ ensures  principal(sender, _) &*&
             [f1]cryptogram(enc_key, KEY_SIZE, enc_key_ccs, enc_key_cg) &*&
             [f2]cryptogram(hmac_key, KEY_SIZE, hmac_key_ccs, hmac_key_cg) &*&
             [f3]crypto_chars(secret, msg, msg_len, msg_ccs); @*/
{
  //@ open principal(sender, _);
  int socket;
  havege_state havege_state;

  char iv[16];
  unsigned int iv_off = 0;
  char hmac[64];
  aes_context aes_context;
  
  net_usleep(20000);
  if(net_connect(&socket, NULL, SERVER_PORT) != 0)
    abort();
  if(net_set_block(socket) != 0)
    abort();
  {
    int message_len = 16 + (int) msg_len + 64;
    char* message = malloc(message_len);
    if (message == 0) abort();

    // IV stuff
    //@ close havege_state(&havege_state);
    havege_init(&havege_state);
    //@ close random_request(sender, 0, false);
    if (havege_random(&havege_state, iv, 16) != 0) abort();
    //@ open cryptogram(iv, 16, ?iv_ccs, ?iv_cg);
    //@ close enc_then_hmac_pub(iv_cg);
    //@ leak enc_then_hmac_pub(iv_cg);
    memcpy(message, iv, 16);
    //@ close cryptogram(message, 16, iv_ccs, iv_cg);
    //@ public_cryptogram(message, iv_cg);
    //@ assert chars(message, 16, ?iv_cs);
    //@ public_chars(message, 16);
    havege_free(&havege_state);
    //@ open havege_state(&havege_state);

    // encrypt
    //@ close aes_context(&aes_context);
    if (aes_setkey_enc(&aes_context, enc_key,
                        (unsigned int) (KEY_SIZE * 8)) != 0)
      abort();
    if (aes_crypt_cfb128(&aes_context, AES_ENCRYPT, msg_len,
                         &iv_off, iv, msg, message + 16) != 0)
      abort();
    //@ open cryptogram(message + 16, msg_len, ?enc_ccs, ?enc_cg);
    //@ close cryptogram(message + 16, msg_len, enc_ccs, enc_cg);
    //@ close enc_then_hmac_pub(enc_cg);
    //@ leak enc_then_hmac_pub(enc_cg);
    //@ public_cryptogram(message + 16, enc_cg);
    //@ assert chars(message + 16, msg_len, ?enc_cs);
    //@ public_chars(message + 16, msg_len);
    //@ assert chars(message, 16 + msg_len, append(iv_cs, enc_cs));
    //@ assert enc_cg == cg_encrypted(sender, enc_id, msg_ccs, iv_ccs);
    zeroize(iv, 16);
    aes_free(&aes_context);
    //@ open aes_context(&aes_context);
    
    // hmac
    //@ chars_to_crypto_chars(message, 16 + msg_len);
    //@ HASH_PUB_PAYLOAD(append(iv_cs, enc_cs))
    sha512_hmac(hmac_key, KEY_SIZE, message,
                (unsigned int) (16 + (int) msg_len),
                message + 16 + (int) msg_len, 0);
    //@ assert cryptogram(message + 16 + msg_len, 64, ?hmac_ccs, ?hmac_cg);
    //@ cs_to_ccs_append(iv_cs, enc_cs);
    //@ assert hmac_cg == cg_hmac(sender, hmac_id, append(iv_ccs, enc_ccs));
    /*@ if (!col && !enc_then_hmac_public_key(sender, enc_id, true))
          close enc_then_hmac_pub_1(enc_id, msg_ccs, iv_ccs); @*/
    /*@ if (col || enc_then_hmac_public_key(sender, enc_id, true))
        { 
          assert [_]public_ccs(iv_ccs);
          assert [_]public_ccs(enc_ccs);
          public_ccs_join(iv_ccs, enc_ccs);
        }
    @*/
    //@ close enc_then_hmac_pub(hmac_cg);
    //@ leak enc_then_hmac_pub(hmac_cg);
    //@ public_cryptogram(message + 16 + msg_len, hmac_cg);
    //@ assert chars(message + 16 + msg_len, 64, ?hmac_cs);
    //@ append_assoc(iv_ccs, enc_ccs, hmac_ccs);
    //@ append_assoc(iv_cs, enc_cs, hmac_cs);
    //@ cs_to_ccs_crypto_chars(message, append(iv_cs, enc_cs));
    /*@ assert chars(message, message_len,
                     append(iv_cs, append(enc_cs, hmac_cs))); @*/
    net_send(&socket, message, (unsigned int) message_len);
    
    free(message);
  }
  net_close(socket);
  //@ close principal(sender, _);
}
Пример #9
0
int receiver(char *enc_key, char *hmac_key, char *msg)
/*@ requires [_]public_invar(enc_then_hmac_pub) &*&
             [_]decryption_key_classifier(enc_then_hmac_public_key) &*&
             principal(?receiver, _) &*&
             [?f1]cryptogram(enc_key, KEY_SIZE, ?enc_key_ccs, ?enc_key_cg) &*&
             [?f2]cryptogram(hmac_key, KEY_SIZE, ?hmac_key_ccs, ?hmac_key_cg) &*&
               enc_key_cg == cg_symmetric_key(?sender, ?enc_id) &*&
               hmac_key_cg == cg_symmetric_key(sender, ?hmac_id) &*&
                 cg_info(hmac_key_cg) == enc_id &*&
               receiver == shared_with(sender, enc_id) &*&
               receiver == shared_with(sender, hmac_id) &*&
             chars(msg, MAX_SIZE, _); @*/
/*@ ensures  principal(receiver, _) &*&
             [f1]cryptogram(enc_key, KEY_SIZE, enc_key_ccs, enc_key_cg) &*&
             [f2]cryptogram(hmac_key, KEY_SIZE, hmac_key_ccs, hmac_key_cg) &*&
             chars(msg + result, MAX_SIZE - result, _) &*&
             crypto_chars(?kind, msg, result, ?msg_ccs) &*&
             col || bad(sender) || bad(receiver) ||
               (kind == secret && send(sender, receiver, msg_ccs)); @*/
{
  //@ open principal(receiver, _);
  int socket1;
  int socket2;

  int size;
  int enc_size;
  char iv[16];
  unsigned int iv_off = 0;
  char hmac[64];
  aes_context aes_context;

  if(net_bind(&socket1, NULL, SERVER_PORT) != 0)
    abort();
  if(net_accept(socket1, &socket2, NULL) != 0)
    abort();
  if(net_set_block(socket2) != 0)
    abort();

  {
    int max_size = 16 + MAX_SIZE + 64;
    char *buffer = malloc (max_size); if (buffer == 0) abort();
    size = net_recv(&socket2, buffer, (unsigned int) max_size);
    if (size <= 16 + 64) abort();
    enc_size = size - 16 - 64;
    if (enc_size < MINIMAL_STRING_SIZE) abort();
    //@ chars_split(buffer, size);
    //@ assert chars(buffer, size, ?all_cs);
    //@ close hide_chars((void*) buffer + size, max_size - size, _);

    //Verify the hmac
    //@ chars_split(buffer, size - 64);
    //@ public_chars(buffer + size - 64, 64);
    //@ assert chars(buffer + size - 64, 64, ?hmac_cs);
    //@ assert chars(buffer, size - 64, ?pay_cs);
    //@ chars_to_crypto_chars(buffer, size - 64);
    //@ HASH_PUB_PAYLOAD(pay_cs)
    sha512_hmac(hmac_key, KEY_SIZE, buffer,
                (unsigned int) (size - 64), hmac, 0);
    //@ open cryptogram(hmac, 64, ?hmac_ccs, ?hmac_cg);
    //@ chars_to_crypto_chars((void*) buffer + size - 64, 64);
    //@ close memcmp_secret(hmac, 64, hmac_ccs, hmac_cg);
    if (memcmp((void*) buffer + size - 64, hmac, 64) != 0) abort();
    /*@ if (!col) 
        {
          public_ccs_cg(hmac_cg);
          public_crypto_chars(hmac, 64);
        }
        else
        {
          crypto_chars_to_chars(hmac, 64);
        }
    @*/
    //@ assert all_cs == append(pay_cs, hmac_cs);

    // IV stuff
    //@ cs_to_ccs_crypto_chars(buffer, pay_cs);
    //@ chars_split(buffer, 16);
    //@ assert chars(buffer, 16, ?iv_cs);
    //@ chars_to_crypto_chars(buffer, 16);
    //@ assert crypto_chars(normal, buffer, 16, ?iv_ccs);
    memcpy(iv, buffer, 16);
    //@ cs_to_ccs_crypto_chars(iv, iv_cs);
    //@ interpret_nonce(iv, 16);
    //@ open cryptogram(iv, 16, iv_ccs, ?iv_cg);

    //Decrypt
    //@ assert chars(buffer + 16, enc_size, ?enc_cs);
    //@ interpret_encrypted(buffer + 16, enc_size);
    //@ open cryptogram(buffer + 16, enc_size, ?enc_ccs, ?enc_cg);
    //@ close cryptogram(buffer + 16, enc_size, enc_ccs, enc_cg);
    //@ assert enc_cg == cg_encrypted(?p2, ?c2, ?dec_ccs2, ?iv_ccs2);
    //@ close aes_context(&aes_context);
    if (aes_setkey_enc(&aes_context, enc_key,
                        (unsigned int) (KEY_SIZE * 8)) != 0)
      abort();
    //@ structure s = known_value(0, dec_ccs2);
    //@ close decryption_pre(true, false, receiver, s, enc_ccs);
    if (aes_crypt_cfb128(&aes_context, AES_DECRYPT, (unsigned int) enc_size,
                         &iv_off, iv, buffer + 16, msg) != 0)
      abort();
    //@ assert pay_cs == append(iv_cs, enc_cs);
    //@ cs_to_ccs_append(iv_cs, enc_cs);
    zeroize(iv, 16);
    aes_free(&aes_context);
    
    //@ open aes_context(&aes_context);
    //@ public_cg_ccs(enc_cg);
    //@ public_cryptogram(buffer + 16, enc_cg);
    /*@ open decryption_post(true, ?garbage, receiver,
                             s, sender, enc_id, ?dec_ccs); @*/
    /*@ if (!col)
        {
          open [_]enc_then_hmac_pub(hmac_cg);
          open [_]enc_then_hmac_pub(enc_cg);
          if (!enc_then_hmac_public_key(sender, enc_id, true))
          {
            assert [_]enc_then_hmac_pub_1(?id, ?dec_ccs3, ?ent);
            cryptogram enc_cg3 = cg_encrypted(sender, id, dec_ccs3, ent);
            take_append(16, iv_ccs, ccs_for_cg(enc_cg));
            take_append(16, ent, ccs_for_cg(enc_cg3));
            assert ent == iv_ccs;
            drop_append(16, iv_ccs, ccs_for_cg(enc_cg));
            drop_append(16, ent, ccs_for_cg(enc_cg3));
            assert ccs_for_cg(enc_cg) == ccs_for_cg(enc_cg3);
            ccs_for_cg_inj(enc_cg, enc_cg3);
            assert dec_ccs2 == dec_ccs3;
            close exists(pair(nil, nil));
            close has_structure(dec_ccs2, s);
            leak has_structure(dec_ccs2, s);
          }
        }
        else
        {
          crypto_chars_to_chars(msg, enc_size);
          chars_to_secret_crypto_chars(msg, enc_size);
        }
    @*/
    //@ if (garbage) decryption_garbage(msg, enc_size, s);
    //@ open hide_chars((void*) buffer + size, max_size - size, _);
    //@ crypto_chars_to_chars(buffer, 16);
    //@ crypto_chars_to_chars(buffer + size - 64, 64);
    //@ chars_join(buffer);
    //@ chars_join(buffer);
    free(buffer);
  }
  net_close(socket2);
  net_close(socket1);
  return enc_size;
  //@ close principal(receiver, _);
}
Пример #10
0
void attacker()
  /*@ requires [_]public_invar(?pub) &*&
               [_]decryption_key_classifier(?classifier) &*&
               public_invariant_constraints(pub, ?proof_pred) &*&
               proof_pred() &*& principal(?bad_one, _) &*& true == bad(bad_one) &*&
               is_public_key_classifier(_, pub, classifier, proof_pred); @*/
  /*@ ensures  public_invariant_constraints(pub, proof_pred) &*&
               proof_pred() &*& principal(bad_one, _) &*&
               is_public_key_classifier(_, pub, classifier, proof_pred); @*/
{
  bool havege_failure = false;
  int server_or_client;
  int port;
  int* socket;
  int socket1;
  int socket2;
  //@ open principal(bad_one, _);

  havege_state havege_state;
  //@ close havege_state(&havege_state);
  havege_init(&havege_state);

  //@ open public_invariant_constraints(pub, proof_pred);
  /*@
  {
    lemma void principal_with_public_nonces(cryptogram nonce)
      requires  is_bad_nonce_is_public(?proof, pub, proof_pred) &*&
                proof_pred() &*&
                nonce == cg_nonce(bad_one, _);
      ensures   is_bad_nonce_is_public(proof, pub, proof_pred) &*&
                proof_pred() &*&
                [_]pub(nonce);
    {
      proof(nonce);
    }
    produce_lemma_function_pointer_chunk(principal_with_public_nonces) :
      principal_with_public_nonces
        (pub, attacker_nonce_pred(pub, proof_pred), bad_one)(nonce__)
        {
          open attacker_nonce_pred(pub, proof_pred)();
          call();
          close attacker_nonce_pred(pub, proof_pred)();
        }
    {duplicate_lemma_function_pointer_chunk(principal_with_public_nonces);};
  }
  @*/
  //@ close_havege_util(pub, proof_pred, bad_one);
  r_int(&havege_state, &server_or_client);
  r_int(&havege_state, &port);
  //@ open_havege_util(pub, proof_pred, bad_one);

  bool network_failure = false;

  if (server_or_client % 2 == 0)
  {
    if(net_connect(&socket1, NULL, port) != 0) network_failure = true;
    else if(net_set_block(socket1) != 0) network_failure = true;
    socket = &socket1;
  }
  else
  {
    if(net_bind(&socket1, NULL, port) != 0)
      {network_failure = true;}
    else if(net_accept(socket1, &socket2, NULL) != 0)
      {net_close(socket1); network_failure = true;}
    else if(net_set_block(socket2) != 0)
      {net_close(socket1); network_failure = true;}
    socket = &socket2;
  }

  if (!network_failure)
  {
    //@ close attacker_invariant(pub, proof_pred, ?kc, &havege_state, socket, bad_one);
    int j = 0;
    while(j < POLARSSL_ATTACKER_ITERATIONS)
      /*@ invariant attacker_invariant(pub, proof_pred, kc,
                                       &havege_state, socket, bad_one); @*/
    {
      attacker_core(&havege_state, socket);
      j++;
    }
    //@ open attacker_invariant(pub, proof_pred, kc, &havege_state, socket, bad_one);

    if (server_or_client % 2 == 0)
      net_close(socket1);
    else
    {
      net_close(socket1);
      net_close(socket2);
    }
  }

  //@ close public_invariant_constraints(pub, proof_pred);
  //@ close principal(bad_one, _);
  havege_free(&havege_state);
  //@ open havege_state(&havege_state);
  /*@ leak is_principal_with_public_nonces(_, pub,
                            attacker_nonce_pred(pub, proof_pred), bad_one); @*/
}