Ejemplo n.º 1
0
int
tcp_rcv(PACKET pkt)     /* NOTE: pkt has nb_prot pointing to IP header */
{
   struct mbuf *  m_in;
   struct ip * bip;  /* IP header, berkeley version */
   struct tcphdr *   tcpp;
   unshort  len;  /* scratch length holder */

   /* For TCP, the netport IP layer is modified to set nb_prot to the 
    * start of the IP header (not TCP). We need to do some further
    * mods which the BSD code expects:
    */
   bip = (struct ip *)pkt->nb_prot;    /* get ip header */
   len = ntohs(bip->ip_len);  /* get length in local endian */

   /* verify checksum of received packet */

   tcpp = (struct tcphdr *)ip_data(bip);
   if (tcp_cksum(bip) != tcpp->th_sum)
   {
      TCP_MIB_INC(tcpInErrs);    /* keep MIB stats */
      tcpstat.tcps_rcvbadsum++;  /* keep BSD stats */
      LOCK_NET_RESOURCE(FREEQ_RESID);
      pk_free(pkt);  /* punt packet */
      UNLOCK_NET_RESOURCE(FREEQ_RESID);
      return ENP_BAD_HEADER;
   }

   m_in = m_getnbuf(MT_RXDATA, 0);
   if (!m_in){
      LOCK_NET_RESOURCE(FREEQ_RESID);
      pk_free(pkt);
      UNLOCK_NET_RESOURCE(FREEQ_RESID);
      return ENP_RESOURCE;  
   }

   IN_PROFILER(PF_TCP, PF_ENTRY);      /* measure time in TCP */

   /* subtract IP header length from total IP packet length */
   len -= ((unshort)(bip->ip_ver_ihl & 0x0f) << 2);
   bip->ip_len = len;   /* put TCP length in struct for TCP code to use */

   /* set mbuf to point to start of IP header (not TCP) */
   m_in->pkt = pkt;
   m_in->m_data = pkt->nb_prot;
   m_in->m_len = pkt->nb_plen;
   m_in->m_base = pkt->nb_buff;     /* ??? */
   m_in->m_memsz = pkt->nb_blen;    /* ??? */

   tcp_input(m_in, pkt->net);

   IN_PROFILER(PF_TCP, PF_EXIT);      /* measure time in TCP */

   return 0;
}
Ejemplo n.º 2
0
void
rfsim_timer()
{
   ip_addr     hop;
   struct ip * pip;
   PACKET      pkt;

   /* send al packets which have timed out */
   while(((PACKET)(simq.q_head))->nb_tstamp < cticks)
   {
      pkt = (PACKET)getq(&simq); /* get pkt to send */
      hop = pkt->fhost;          /* get hop from host field */
      pip = ip_head(pkt);        /* get real host address */
      pkt->fhost = pip->ip_dest; /* restore host field */
      simpkts++;

      /* see if it's time to drop a packet */
      if((lossrate) && 
         ((simpkts - simlastloss) > lossrate) && 
         ((cticks & deviation) == 1))
      {
         LOCK_NET_RESOURCE(FREEQ_RESID);
         pk_free(pkt);           /* drop instead of send */
         UNLOCK_NET_RESOURCE(FREEQ_RESID);
         simlastloss = simpkts;  /* reset drop timer */
         simdrops++;             /* count drops */
      }
      else
         ip2mac(pkt, hop);          /* send pkt to hardware */
   }
   return;
}
Ejemplo n.º 3
0
		~cPubKey()
		{
			if (m_IsValid)
			{
				pk_free(&m_Key);
			}
		}
Ejemplo n.º 4
0
/*
 * Unallocate all CSR data
 */
void x509_csr_free( x509_csr *csr )
{
    x509_name *name_cur;
    x509_name *name_prv;

    if( csr == NULL )
        return;

    pk_free( &csr->pk );

    name_cur = csr->subject.next;
    while( name_cur != NULL )
    {
        name_prv = name_cur;
        name_cur = name_cur->next;
        memset( name_prv, 0, sizeof( x509_name ) );
        polarssl_free( name_prv );
    }

    if( csr->raw.p != NULL )
    {
        memset( csr->raw.p, 0, csr->raw.len );
        polarssl_free( csr->raw.p );
    }

    memset( csr, 0, sizeof( x509_csr ) );
}
Ejemplo n.º 5
0
/*
 * Unallocate all CSR data
 */
void x509_csr_free( x509_csr *csr )
{
    x509_name *name_cur;
    x509_name *name_prv;

    if( csr == NULL )
        return;

    pk_free( &csr->pk );

#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
    polarssl_free( csr->sig_opts );
#endif

    name_cur = csr->subject.next;
    while( name_cur != NULL )
    {
        name_prv = name_cur;
        name_cur = name_cur->next;
        polarssl_zeroize( name_prv, sizeof( x509_name ) );
        polarssl_free( name_prv );
    }

    if( csr->raw.p != NULL )
    {
        polarssl_zeroize( csr->raw.p, csr->raw.len );
        polarssl_free( csr->raw.p );
    }

    polarssl_zeroize( csr, sizeof( x509_csr ) );
}
Ejemplo n.º 6
0
PACKET
pk_prepend(PACKET pkt, int bigger)
{
   PACKET newpkt;

   LOCK_NET_RESOURCE(FREEQ_RESID);
   newpkt = pk_alloc(bigger);
   UNLOCK_NET_RESOURCE(FREEQ_RESID);
   if(!newpkt)
   {
      LOCK_NET_RESOURCE(FREEQ_RESID);
      pk_free(pkt);
      UNLOCK_NET_RESOURCE(FREEQ_RESID);
      return NULL;
   }
   newpkt->nb_prot = newpkt->nb_buff;  /* no MAC prepend */

   /* set lengths of this buffer - no data yet */
   newpkt->nb_plen = 0;       /* nothing in this buffer */
   newpkt->nb_tlen = pkt->nb_tlen;  /* total chain length unchanged */

   newpkt->pk_next = pkt;
   newpkt->pk_prev = NULL;
   /* ensure that the newly allocated buffer's PKF_HEAPBUF and 
    * PKF_INTRUNSAFE flags aren't overwritten */
   newpkt->flags |= (pkt->flags & (~(PKF_HEAPBUF | PKF_INTRUNSAFE)));
   newpkt->net = pkt->net;
   pkt->pk_prev = newpkt;     /* link new pkt */
   return(newpkt);
}
Ejemplo n.º 7
0
/*
 *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
 *       algorithm            AlgorithmIdentifier,
 *       subjectPublicKey     BIT STRING }
 */
int pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
                        pk_context *pk )
{
    int ret;
    size_t len;
    asn1_buf alg_params;
    pk_type_t pk_alg = POLARSSL_PK_NONE;
    const pk_info_t *pk_info;

    if( ( ret = asn1_get_tag( p, end, &len,
                    ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
    }

    end = *p + len;

    if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 )
        return( ret );

    if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
        return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );

    if( *p + len != end )
        return( POLARSSL_ERR_PK_INVALID_PUBKEY +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );

    if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL )
        return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );

    if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 )
        return( ret );

#if defined(POLARSSL_RSA_C)
    if( pk_alg == POLARSSL_PK_RSA )
    {
        ret = pk_get_shrsapubkey( p, end, pk_rsa( *pk ) );
    } else
#endif /* POLARSSL_RSA_C */
#if defined(POLARSSL_ECP_C)
    if( pk_alg == POLARSSL_PK_ECKEY_DH || pk_alg == POLARSSL_PK_ECKEY )
    {
        ret = pk_use_ecparams( &alg_params, &pk_ec( *pk )->grp );
        if( ret == 0 )
            ret = pk_get_ecpubkey( p, end, pk_ec( *pk ) );
    } else
#endif /* POLARSSL_ECP_C */
        ret = POLARSSL_ERR_PK_UNKNOWN_PK_ALG;

    if( ret == 0 && *p != end )
        ret = POLARSSL_ERR_PK_INVALID_PUBKEY
              POLARSSL_ERR_ASN1_LENGTH_MISMATCH;

    if( ret != 0 )
        pk_free( pk );

    return( ret );
}
Ejemplo n.º 8
0
      void dealloc()
      {
	if (ctx)
	  {
	    pk_free(ctx);
	    delete ctx;
	    ctx = NULL;
	  }
      }
Ejemplo n.º 9
0
struct mbuf *  
m_getnbuf(int type, int len)
{
   struct mbuf *  m;
   PACKET pkt = NULL;

#ifdef NPDEBUG
   if (type < MT_RXDATA || type > MT_IFADDR)
   {
      dtrap(); /* is this OK? */
   }
#endif

   /* if caller has data (len >= 0), we need to allocate 
    * a packet buffer; else all we need is the mbuf */
   if (len != 0)
   {
      LOCK_NET_RESOURCE(FREEQ_RESID);
      pkt = pk_alloc(len + HDRSLEN);

      UNLOCK_NET_RESOURCE(FREEQ_RESID);
      if (!pkt)
         return NULL;
   }

   m = (struct mbuf *)getq(&mfreeq);
   if (!m)
   {
      if (pkt) 
      {
         LOCK_NET_RESOURCE(FREEQ_RESID);
         pk_free(pkt);
         UNLOCK_NET_RESOURCE(FREEQ_RESID);
      }
      return NULL;
   }
   m->m_type = type;
   if (len == 0)
   {
      m->pkt = NULL;
      m->m_base = NULL;    /* caller better fill these in! */
      m->m_memsz = 0;
   }
   else
   {
      m->pkt = pkt;
      /* set m_data to the part where tcp data should go */
      m->m_base = m->m_data = pkt->nb_prot = pkt->nb_buff + HDRSLEN;
      m->m_memsz = pkt->nb_blen - HDRSLEN;
   }
   m->m_len = 0;
   m->m_next = m->m_act = NULL;
   mbstat.allocs++;        /* maintain local statistics */
   putq(&mbufq, (qp)m);
   return m;
}
Ejemplo n.º 10
0
__hidden void __ustream_ssl_context_free(struct ustream_ssl_ctx *ctx)
{
#ifdef USE_VERSION_1_3
    pk_free(&ctx->key);
    x509_crt_free(&ctx->cert);
#else
    rsa_free(&ctx->key);
    x509_free(&ctx->cert);
#endif
    free(ctx);
}
Ejemplo n.º 11
0
int igmpv2_input (PACKET p)
{
   struct igmp * igmp;
   struct ip * pip;
   int igmplen;
   u_char type;
   int rc;

   pip = ip_head (p);    
   /* compute length of IGMP packet (after accounting for IP header, 
    * including the IP Router Alert option (if present)) */   
   igmplen = p->nb_plen - ip_hlen (pip);
   igmp = (struct igmp *) (ip_data (pip));   
   /* extract the IGMP packet type from received packet */
   type = igmp->igmp_type;

   switch (type) 
   {
      case IGMP_HOST_MEMBERSHIP_QUERY:
         rc = igmpv2_process_query (p);
         break;

      case IGMP_HOST_MEMBERSHIP_REPORT:
      case IGMPv2_MEMBERSHIP_REPORT:
         rc = igmpv2_process_report (p);
         break;
         
      case IGMPv2_LEAVE_GROUP:
         /* Leave messages are typically addressed to the all-routers 
          * multicast address group (224.0.0.2).  We do not implement 
          * multicast router functionality, and therefore, do not 
          * expect to receive such messages.  However, according to
          * RFC 2236, some implementations of an older version of the 
          * IGMPv2 specification send leave messages to the group 
          * being left.  If we do receive such a message, we will 
          * drop it. */       
         ++igmpstats.igmpv2mode_v2_leave_msgs_rcvd;
         rc = IGMP_OK;
         break;               

      default:     
         ++igmpstats.igmpv2mode_unknown_pkttype;
         rc = IGMP_ERR;         
         break;
   } /* end SWITCH */

   /* we're done processing the received packet; return packet buffer 
    * back to free pool */
   LOCK_NET_RESOURCE(FREEQ_RESID);
   pk_free(p);
   UNLOCK_NET_RESOURCE(FREEQ_RESID);
   
   return rc;
}
Ejemplo n.º 12
0
void ms_dtls_srtp_context_destroy(MSDtlsSrtpContext *ctx) {
	/* clean polarssl contexts */
	if (ctx->rtp_dtls_context) {
		x509_crt_free( &(ctx->rtp_dtls_context->crt) );
		ssl_free( &(ctx->rtp_dtls_context->ssl) );
		ctr_drbg_free( &(ctx->rtp_dtls_context->ctr_drbg) );
		entropy_free( &(ctx->rtp_dtls_context->entropy) );
		pk_free( &(ctx->rtp_dtls_context->pkey) );
		ssl_cookie_free( &(ctx->rtp_dtls_context->cookie_ctx) );
		ms_mutex_destroy(&ctx->rtp_dtls_context->ssl_context_mutex);
		ms_free(ctx->rtp_dtls_context);
	}
	if (ctx->rtcp_dtls_context) {
		x509_crt_free( &(ctx->rtcp_dtls_context->crt) );
		ssl_free( &(ctx->rtcp_dtls_context->ssl) );
		ctr_drbg_free( &(ctx->rtcp_dtls_context->ctr_drbg) );
		entropy_free( &(ctx->rtcp_dtls_context->entropy) );
		pk_free( &(ctx->rtcp_dtls_context->pkey) );
		ssl_cookie_free( &(ctx->rtcp_dtls_context->cookie_ctx) );
		ms_mutex_destroy(&ctx->rtcp_dtls_context->ssl_context_mutex);
		ms_free(ctx->rtcp_dtls_context);
	}
	/* clean incoming buffers */
	while (ctx->rtp_incoming_buffer!=NULL) {
		DtlsRawPacket *next_packet = ctx->rtp_incoming_buffer->next;
		ms_free(ctx->rtp_incoming_buffer->data);
		ms_free(ctx->rtp_incoming_buffer);
		ctx->rtp_incoming_buffer = next_packet;
	}
	while (ctx->rtcp_incoming_buffer!=NULL) {
		DtlsRawPacket *next_packet = ctx->rtcp_incoming_buffer->next;
		ms_free(ctx->rtcp_incoming_buffer->data);
		ms_free(ctx->rtcp_incoming_buffer);
		ctx->rtcp_incoming_buffer = next_packet;
	}

	ms_free(ctx);
	ms_message("DTLS-SRTP context destroyed");
}
Ejemplo n.º 13
0
PACKET
pk_gather(PACKET pkt, int headerlen)
{
   PACKET   newpkt;
   PACKET   tmppkt;
   int      oldlen, newlen;
   char *   cp;

   oldlen = pkt->nb_tlen;

   LOCK_NET_RESOURCE(FREEQ_RESID);
   newpkt = pk_alloc(oldlen + headerlen);
   UNLOCK_NET_RESOURCE(FREEQ_RESID);
   if(!newpkt)
      return NULL;

   newpkt->nb_prot = newpkt->nb_buff + headerlen;
   /* ensure that the newly allocated buffer's PKF_HEAPBUF and 
    * PKF_INTRUNSAFE flags aren't overwritten */
   newpkt->flags |= (pkt->flags & (~(PKF_HEAPBUF | PKF_INTRUNSAFE)));
   newpkt->net = pkt->net;
   newpkt->pk_prev = newpkt->pk_next = NULL;

   tmppkt = pkt;        /* save packet for pk_free call below */
   newlen = 0;
   cp = newpkt->nb_prot;
   while(pkt)
   {
      MEMCPY(cp, pkt->nb_prot, pkt->nb_plen);
      newlen += pkt->nb_plen;
      cp += pkt->nb_plen;  /* bump pointer to data */
      pkt = pkt->pk_next;  /* next packet in chain */
   }
   LOCK_NET_RESOURCE(FREEQ_RESID);
   pk_free(tmppkt);     /* free last packet in chain */
   UNLOCK_NET_RESOURCE(FREEQ_RESID);
   if(newlen != oldlen)    /* make sure length was right */
      panic("pk_gather");

   newpkt->nb_plen = newlen;
   return newpkt;
}
Ejemplo n.º 14
0
int igmp_input (PACKET p)
{
    u_char mode;
    int rc;

    ++igmpstats.igmp_total_rcvd;

    /* validate the received packet; if validation fails,
     * drop the packet and return */
    if ((rc = igmp_validate (p)) != IGMP_OK) goto end;

    /* determine the operating mode for IGMP on the ingress link */
    mode = p->net->igmp_oper_mode;

    /* feed packet to IGMPv1 or IGMPv2 code based on the operating
     * mode of the ingress link */
    switch (mode)
    {
#ifdef IGMP_V1
    case IGMP_MODE_V1:
        return (igmpv1_input (p));
#endif
#ifdef IGMP_V2
    case IGMP_MODE_V2:
        return (igmpv2_input (p));
#endif
    default:
        ++igmpstats.igmp_bad_oper_mode;
        rc = IGMP_ERR;
        break;
    }

end:
    /* return packet buffer back to free pool */
    LOCK_NET_RESOURCE(FREEQ_RESID);
    pk_free(p);
    UNLOCK_NET_RESOURCE(FREEQ_RESID);

    return rc;
}
Ejemplo n.º 15
0
struct mbuf *  
m_free(struct mbuf * m)
{
   struct mbuf *  nextptr;

#ifdef NPDEBUG
   if (mbufq.q_len < 1)
      panic("mfree: q_len");

   if (m->m_type < MT_RXDATA || m->m_type > MT_IFADDR)
   {
      if (m->m_type == MT_FREE)
      {
         dtrap(); /* debug double free of mbuf by tcp_in() */
         return m->m_next; /* seems harmless, though.... */
      }
      else
         panic("m_free: type");
   }
#endif   /* NPDEBUG */

   nextptr = m->m_next;    /* remember value to return */

   if (qdel(&mbufq, m) == NULL)
      panic("m_free: missing");

   m->m_type = MT_FREE;    /* this may seem silly, but helps error checking */

   if (m->pkt)
   {
      LOCK_NET_RESOURCE(FREEQ_RESID);
      pk_free(m->pkt);     /* free up the netport buffer */
      UNLOCK_NET_RESOURCE(FREEQ_RESID);
   }
   mbstat.frees++;
   putq(&mfreeq, (qp)m);
   return nextptr;
}
Ejemplo n.º 16
0
static mrb_value mrb_ecdsa_load_pem(mrb_state *mrb, mrb_value self) {
  ecdsa_context *ecdsa;
  pk_context pkey;
  mrb_value pem;
  int ret = 0;

  mrb_get_args(mrb, "S", &pem);

  pk_init( &pkey );

  ret = pk_parse_key(&pkey, RSTRING_PTR(pem), RSTRING_LEN(pem), NULL, 0);
  if (ret == 0) {
    ecdsa = DATA_CHECK_GET_PTR(mrb, self, &mrb_ecdsa_type, ecdsa_context);
    ret = ecdsa_from_keypair(ecdsa, pk_ec(pkey));
    if (ret == 0) {
      return mrb_true_value();
    }
  }

  pk_free( &pkey );
  mrb_raise(mrb, E_RUNTIME_ERROR, "can't parse pem");
  return mrb_false_value();
}
Ejemplo n.º 17
0
int main( int argc, char *argv[] )
{
    int ret = 0, len, written, frags;
    int listen_fd;
    int client_fd = -1;
    unsigned char buf[1024];
#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
    unsigned char psk[256];
    size_t psk_len = 0;
#endif
    const char *pers = "ssl_server2";

    entropy_context entropy;
    ctr_drbg_context ctr_drbg;
    ssl_context ssl;
#if defined(POLARSSL_X509_CRT_PARSE_C)
    x509_crt cacert;
    x509_crt srvcert;
    pk_context pkey;
    x509_crt srvcert2;
    pk_context pkey2;
    int key_cert_init = 0, key_cert_init2 = 0;
#endif
#if defined(POLARSSL_SSL_CACHE_C)
    ssl_cache_context cache;
#endif
#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
    unsigned char alloc_buf[100000];
#endif

    int i;
    char *p, *q;
    const int *list;

#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
    memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
#endif

    /*
     * Make sure memory references are valid in case we exit early.
     */
    listen_fd = 0;
    memset( &ssl, 0, sizeof( ssl_context ) );
#if defined(POLARSSL_X509_CRT_PARSE_C)
    x509_crt_init( &cacert );
    x509_crt_init( &srvcert );
    pk_init( &pkey );
    x509_crt_init( &srvcert2 );
    pk_init( &pkey2 );
#endif
#if defined(POLARSSL_SSL_CACHE_C)
    ssl_cache_init( &cache );
#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_addr         = DFL_SERVER_ADDR;
    opt.server_port         = DFL_SERVER_PORT;
    opt.debug_level         = DFL_DEBUG_LEVEL;
    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.crt_file2           = DFL_CRT_FILE2;
    opt.key_file2           = DFL_KEY_FILE2;
    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.min_version         = DFL_MIN_VERSION;
    opt.max_version         = DFL_MAX_VERSION;
    opt.auth_mode           = DFL_AUTH_MODE;
    opt.mfl_code            = DFL_MFL_CODE;
    opt.tickets             = DFL_TICKETS;

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

        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, "server_addr" ) == 0 )
            opt.server_addr = q;
        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, "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, "crt_file2" ) == 0 )
            opt.crt_file2 = q;
        else if( strcmp( p, "key_file2" ) == 0 )
            opt.key_file2 = 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] = -1;

            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, "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, "tickets" ) == 0 )
        {
            opt.tickets = atoi( q );
            if( opt.tickets < 0 || opt.tickets > 1 )
                goto usage;
        }
        else
            goto usage;
    }

    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 */

    /*
     * 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 ) )
        ret = x509_crt_parse_path( &cacert, opt.ca_path );
    else if( strlen( opt.ca_file ) )
        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
     */
    printf( "  . Loading the server cert. and key..." );
    fflush( stdout );

#if defined(POLARSSL_FS_IO)
    if( strlen( opt.crt_file ) )
    {
        key_cert_init++;
        if( ( ret = x509_crt_parse_file( &srvcert, opt.crt_file ) ) != 0 )
        {
            printf( " failed\n  !  x509_crt_parse_file returned -0x%x\n\n",
                    -ret );
            goto exit;
        }
    }
    if( strlen( opt.key_file ) )
    {
        key_cert_init++;
        if( ( ret = pk_parse_keyfile( &pkey, opt.key_file, "" ) ) != 0 )
        {
            printf( " failed\n  !  pk_parse_keyfile returned -0x%x\n\n", -ret );
            goto exit;
        }
    }
    if( key_cert_init == 1 )
    {
        printf( " failed\n  !  crt_file without key_file or vice-versa\n\n" );
        goto exit;
    }

    if( strlen( opt.crt_file2 ) )
    {
        key_cert_init2++;
        if( ( ret = x509_crt_parse_file( &srvcert2, opt.crt_file2 ) ) != 0 )
        {
            printf( " failed\n  !  x509_crt_parse_file(2) returned -0x%x\n\n",
                    -ret );
            goto exit;
        }
    }
    if( strlen( opt.key_file2 ) )
    {
        key_cert_init2++;
        if( ( ret = pk_parse_keyfile( &pkey2, opt.key_file2, "" ) ) != 0 )
        {
            printf( " failed\n  !  pk_parse_keyfile(2) returned -0x%x\n\n",
                    -ret );
            goto exit;
        }
    }
    if( key_cert_init2 == 1 )
    {
        printf( " failed\n  !  crt_file2 without key_file2 or vice-versa\n\n" );
        goto exit;
    }
#endif
    if( key_cert_init == 0 && key_cert_init2 == 0 )
    {
#if !defined(POLARSSL_CERTS_C)
        printf( "Not certificated or key provided, and \n"
                "POLARSSL_CERTS_C not defined!\n" );
        goto exit;
#else
#if defined(POLARSSL_RSA_C)
        if( ( ret = x509_crt_parse( &srvcert,
                                    (const unsigned char *) test_srv_crt_rsa,
                                    strlen( test_srv_crt_rsa ) ) ) != 0 )
        {
            printf( " failed\n  !  x509_crt_parse returned -0x%x\n\n", -ret );
            goto exit;
        }
        if( ( ret = pk_parse_key( &pkey,
                                  (const unsigned char *) test_srv_key_rsa,
                                  strlen( test_srv_key_rsa ), NULL, 0 ) ) != 0 )
        {
            printf( " failed\n  !  pk_parse_key returned -0x%x\n\n", -ret );
            goto exit;
        }
        key_cert_init = 2;
#endif /* POLARSSL_RSA_C */
#if defined(POLARSSL_ECDSA_C)
        if( ( ret = x509_crt_parse( &srvcert2,
                                    (const unsigned char *) test_srv_crt_ec,
                                    strlen( test_srv_crt_ec ) ) ) != 0 )
        {
            printf( " failed\n  !  x509_crt_parse2 returned -0x%x\n\n", -ret );
            goto exit;
        }
        if( ( ret = pk_parse_key( &pkey2,
                                  (const unsigned char *) test_srv_key_ec,
                                  strlen( test_srv_key_ec ), NULL, 0 ) ) != 0 )
        {
            printf( " failed\n  !  pk_parse_key2 returned -0x%x\n\n", -ret );
            goto exit;
        }
        key_cert_init2 = 2;
#endif /* POLARSSL_ECDSA_C */
#endif /* POLARSSL_CERTS_C */
    }

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

    /*
     * 2. Setup the listening TCP socket
     */
    printf( "  . Bind on tcp://localhost:%-4d/ ...", opt.server_port );
    fflush( stdout );

    if( ( ret = net_bind( &listen_fd, opt.server_addr,
                                      opt.server_port ) ) != 0 )
    {
        printf( " failed\n  ! net_bind 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;
    }

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

#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
    ssl_set_max_frag_len( &ssl, opt.mfl_code );
#endif

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

#if defined(POLARSSL_SSL_CACHE_C)
    ssl_set_session_cache( &ssl, ssl_cache_get, &cache,
                                 ssl_cache_set, &cache );
#endif

#if defined(POLARSSL_SSL_SESSION_TICKETS)
    ssl_set_session_tickets( &ssl, opt.tickets );
#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)
    ssl_set_ca_chain( &ssl, &cacert, NULL, NULL );
    if( key_cert_init )
        ssl_set_own_cert( &ssl, &srvcert, &pkey );
    if( key_cert_init2 )
        ssl_set_own_cert( &ssl, &srvcert2, &pkey2 );
#endif

#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
    ssl_set_psk( &ssl, psk, psk_len, (const unsigned char *) opt.psk_identity,
                 strlen( opt.psk_identity ) );
#endif

#if defined(POLARSSL_DHM_C)
    /*
     * Use different group than default DHM group
     */
    ssl_set_dh_param( &ssl, POLARSSL_DHM_RFC5114_MODP_2048_P,
                            POLARSSL_DHM_RFC5114_MODP_2048_G );
#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 );

    printf( " ok\n" );

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

    if( client_fd != -1 )
        net_close( client_fd );

    ssl_session_reset( &ssl );

    /*
     * 3. Wait until a client connects
     */
    client_fd = -1;

    printf( "  . Waiting for a remote connection ..." );
    fflush( stdout );

    if( ( ret = net_accept( listen_fd, &client_fd, NULL ) ) != 0 )
    {
        printf( " failed\n  ! net_accept returned -0x%x\n\n", -ret );
        goto exit;
    }

    ssl_set_bio( &ssl, net_recv, &client_fd,
                       net_send, &client_fd );

    printf( " ok\n" );

    /*
     * 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\n", -ret );
            goto reset;
        }
    }

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

#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( !ssl_get_peer_cert( &ssl ) )
            printf( "  ! no client certificate sent\n" );

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

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

        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 ) )
    {
        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 */

    /*
     * 6. Read the HTTP Request
     */
    printf( "  < Read from client:" );
    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 <= 0 )
        {
            switch( ret )
            {
                case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY:
                    printf( " connection was closed gracefully\n" );
                    break;

                case POLARSSL_ERR_NET_CONN_RESET:
                    printf( " connection was reset by peer\n" );
                    break;

                default:
                    printf( " ssl_read returned -0x%x\n", -ret );
                    break;
            }

            break;
        }

        len = ret;
        printf( " %d bytes read\n\n%s\n", len, (char *) buf );

        if( memcmp( buf, "SERVERQUIT", 10 ) == 0 )
        {
            ret = 0;
            goto exit;
        }

        if( ret > 0 )
            break;
    }
    while( 1 );

    /*
     * 7. Write the 200 Response
     */
    printf( "  > Write to client:" );
    fflush( stdout );

    len = sprintf( (char *) buf, HTTP_RESPONSE,
                   ssl_get_ciphersuite( &ssl ) );

    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_CONN_RESET )
            {
                printf( " failed\n  ! peer closed the connection\n\n" );
                goto reset;
            }

            if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
            {
                printf( " failed\n  ! ssl_write returned %d\n\n", ret );
                goto exit;
            }
        }
    }

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

#ifdef TEST_RENEGO
    /*
     * Request renegotiation (this must be done when the client is still
     * waiting for input from our side).
     */
    printf( "  . Requestion 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;
        }
    }

    /*
     * Should be a while loop, not an if, but here we're not actually
     * expecting data from the client, and since we're running tests locally,
     * we can just hope the handshake will finish the during the first call.
     */
    if( ( ret = ssl_read( &ssl, buf, 0 ) ) != 0 )
    {
        if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
        {
            printf( " failed\n  ! ssl_read returned %d\n\n", ret );

            /* Unexpected message probably means client didn't renegotiate */
            if( ret == POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE )
                goto reset;
            else
                goto exit;
        }
    }

    printf( " ok\n" );
#endif

    ret = 0;
    goto reset;

exit:

#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

    net_close( client_fd );
#if defined(POLARSSL_X509_CRT_PARSE_C)
    x509_crt_free( &cacert );
    x509_crt_free( &srvcert );
    pk_free( &pkey );
    x509_crt_free( &srvcert2 );
    pk_free( &pkey2 );
#endif

    ssl_free( &ssl );
    entropy_free( &entropy );

#if defined(POLARSSL_SSL_CACHE_C)
    ssl_cache_free( &cache );
#endif

#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
#if defined(POLARSSL_MEMORY_DEBUG)
    memory_buffer_alloc_status();
#endif
    memory_buffer_alloc_free();
#endif

#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 );
}
Ejemplo n.º 18
0
struct item *asymmetric_decryption(struct item *key, struct item *item, char tag)
  /*@ requires [?f]world(?pub, ?key_clsfy) &*& true == valid_tag(tag) &*&
               principal(?principal1, ?count1) &*&
               item(item, ?enc, pub) &*& item(key, ?k, pub) &*&
                 enc == asymmetric_encrypted_item(?principal2, ?count2,
                                                  ?pay, ?ent) &*&
               k == private_key_item(?principal3, ?count3); @*/
  /*@ ensures  [f]world(pub, key_clsfy) &*&
               principal(principal1, count1 + 1) &*&
               item(item, enc, pub) &*& item(key, k, pub) &*&
               item(result, ?dec, pub) &*& tag_for_item(dec) == tag &*&
               col ? 
                 [_]pub(dec) 
               : principal2 != principal3 || count2 != count3 ? 
                 true == key_clsfy(principal3, count3, false) &*& 
                 [_]pub(dec) 
               :
                 switch(pay)
                 {
                   case some(dec2):
                     return dec == dec2;
                   case none:
                     return false;
                 }; @*/
{
  struct item* result = 0;
  debug_print("DECRYPTING:\n");
  print_item(item);
  check_is_asymmetric_encrypted(item);

  {
    pk_context context;
    unsigned int olen;
    char output[MAX_PACKAGE_SIZE];

    // Key
    //@ close pk_context(&context);
    //@ open [f]world(pub, key_clsfy);
    pk_init(&context);
    //@ close [f]world(pub, key_clsfy);
    set_private_key(&context, key);
    //@ open [f]world(pub, key_clsfy);
    /*@ assert pk_context_with_key(&context, pk_private,
                                   ?principal, ?count, RSA_BIT_KEY_SIZE); @*/

    // Decryption
    //@ open item(item, enc, pub);
    /*@ assert enc == asymmetric_encrypted_item(principal2, count2,
                                                pay, ent); @*/
    //@ open [_]item_constraints(enc, ?enc_cs, pub);
    //@ assert [_]ic_parts(enc)(?enc_tag, ?enc_cont);
    //@ assert enc_cs == append(enc_tag, enc_cont);
    //@ open [_]ic_cg(enc)(_, ?enc_cg);
    //@ assert enc_cg == cg_asym_encrypted(principal2, count2, ?cs_pay, ent);
    if (item->size - TAG_LENGTH > RSA_KEY_SIZE ||
        item->size - TAG_LENGTH < MINIMAL_STRING_SIZE)
      abort_crypto_lib("Asymmetric decryption failed: incorrect sizes");
    //@ assert item->content |-> ?i_cont &*& item->size |-> ?i_size;
    //@ crypto_chars_split(i_cont, TAG_LENGTH);
    //@ drop_append(TAG_LENGTH, enc_tag, enc_cont);
    //@ assert crypto_chars(secret, i_cont + TAG_LENGTH, i_size - TAG_LENGTH, enc_cont);
    //@ if (col) enc_cg = chars_for_cg_sur(enc_cont, tag_asym_encrypted);
    //@ if (col) public_crypto_chars_extract(i_cont + TAG_LENGTH, enc_cg);
    //@ close cryptogram(i_cont + TAG_LENGTH, i_size - TAG_LENGTH, enc_cont, enc_cg);
    void *random_state = nonces_expose_state();
    //@ close random_state_predicate(havege_state_initialized);
    /*@ produce_function_pointer_chunk random_function(
                      asym_enc_havege_random_stub)
                     (havege_state_initialized)(state, out, len) { call(); } @*/
    //@ open principal(principal1, count1);
    //@ structure s = known_value(0, full_tag(tag));
    //@ close decryption_pre(false, false, principal1, s, enc_cont);
    if(pk_decrypt(&context, item->content + TAG_LENGTH,
                  (unsigned int) item->size - TAG_LENGTH,
                  output, &olen, MAX_PACKAGE_SIZE,
                  asym_enc_havege_random_stub, random_state) != 0)
      abort_crypto_lib("Decryption failed");
    /*@ open decryption_post(false, ?garbage, principal1, 
                             s, ?p_key, ?c_key, ?cs_out); @*/
    //@ assert u_integer(&olen, ?size_out);
    //@ pk_release_context_with_key(&context);
    //@ open cryptogram(i_cont + TAG_LENGTH, i_size - TAG_LENGTH, enc_cont, enc_cg);
    pk_free(&context);
    //@ open pk_context(&context);
    nonces_hide_state(random_state);
    //@ assert chars((void*)output + size_out, MAX_PACKAGE_SIZE - size_out, ?cs_rest);
    result = malloc(sizeof(struct item));
    if (result == 0) {abort_crypto_lib("Malloc failed");}
    result->size = (int) olen;
    if ((int) olen <= MINIMAL_STRING_SIZE)
      abort_crypto_lib("Decryption: Incorrect size");
    result->content = malloc(result->size);
    if (result->content == 0) {abort_crypto_lib("Malloc failed");}
    //@ close [f]world(pub, key_clsfy);
    //@ assert u_integer(&olen, ?olen_val);
    //@ assert crypto_chars(_, output, olen_val, cs_out);
    //@ crypto_chars_split(output, TAG_LENGTH);
    //@ assert crypto_chars(_, output, TAG_LENGTH, ?cs_tag);
    //@ assert crypto_chars(_, (void*) output + TAG_LENGTH, olen_val - TAG_LENGTH, ?cs_i);
    /*@ if (col)
        {
          crypto_chars_to_chars(output, TAG_LENGTH);
          chars_to_crypto_chars(output, TAG_LENGTH);
        }
        else if (!garbage)
        {
          switch(pay)
          {
            case some(pay1):
              open [_]item_constraints(pay1, cs_out, pub);
            case none:
              open [_]ill_formed_item_chars(enc)(cs_out);
              public_generated_split(polarssl_pub(pub), cs_out, TAG_LENGTH);
          }
          public_crypto_chars(output, TAG_LENGTH);
        }
    @*/
    //@ close check_tag2_ghost_args(false, garbage, p_key, c_key, cs_i);
    check_tag2(output, tag);
    //@ if (!garbage) chars_to_secret_crypto_chars(output, TAG_LENGTH);
    //@ crypto_chars_join(output);
    memcpy(result->content, output, olen);
    //@ assert result->content |-> ?cont;
    //@ assert crypto_chars(?kind, cont, olen_val, cs_out);
    zeroize(output, (int) olen);
    //@ close item(item, enc, pub);
    //@ assert enc == asymmetric_encrypted_item(principal2, count2, pay, ent);
    //@ assert col || enc_cg == cg_asym_encrypted(principal2, count2, cs_pay, ent);
    
    /*@ if (col)
        {
          crypto_chars_to_chars(cont, olen_val);
          public_chars(cont, olen_val);
          chars_to_crypto_chars(cont, olen_val);
        }
        else if (garbage)
        {
          assert true == key_clsfy(principal3, count3, false);
          public_chars(cont, olen_val);
          chars_to_crypto_chars(cont, olen_val);
        }
        else
        {
          assert principal2 == principal3;
          assert count2 == count3;
          assert cs_out == cs_pay;
          switch(pay)
          {
            case some(pay1):
              assert [_]item_constraints(pay1, cs_out, pub);
            case none:
              open [_]ill_formed_item_chars(enc)(cs_out);
              assert [_]public_generated(polarssl_pub(pub))(cs_out);
              public_crypto_chars(cont, olen_val);
              chars_to_crypto_chars(cont, olen_val);
          }
        }
    @*/
    parse_item(result->content, (int) olen);
    /*@ if (col || garbage)
        {
          retreive_proof_obligations();
          deserialize_item(cs_out, pub);
          leak proof_obligations(pub);
          chars_to_secret_crypto_chars(cont, olen_val);
        }
    @*/
    //@ open [_]item_constraints(?dec, cs_out, pub);
    //@ assert [_]ic_parts(dec)(?dec_tag, ?dec_cont);
    //@ take_append(TAG_LENGTH, dec_tag, dec_cont);
    //@ drop_append(TAG_LENGTH, dec_tag, dec_cont);
    //@ assert dec_tag == full_tag(tag);
    //@ assert tag_for_item(dec) == tag;
    //@ close item(result, dec, pub);
  }
  return result;
}
Ejemplo n.º 19
0
struct item *asymmetric_encryption(struct item *key, struct item *payload)
  /*@ requires [?f]world(?pub, ?key_clsfy) &*&
               principal(?principal1, ?count1) &*&
               item(payload, ?pay, pub) &*& item(key, ?k, pub) &*&
               k == public_key_item(?principal2, ?count2); @*/
  /*@ ensures  [f]world(pub, key_clsfy) &*&
               principal(principal1, count1 + 1) &*&
               item(payload, pay, pub) &*& item(key, k, pub) &*&
               item(result, ?enc, pub) &*&
               col ? true :
                 enc == asymmetric_encrypted_item(principal2, count2,
                                                  some(pay), ?ent); @*/
{
  debug_print("ASYM ENCRYPTING:\n");
  print_item(payload);

  struct item* result;
  result = malloc(sizeof(struct item));
  if (result == 0) abort_crypto_lib("Malloc failed");

  {
    pk_context context;
    unsigned int olen;
    char output[MAX_PACKAGE_SIZE];

    // Key
    //@ close pk_context(&context);
    //@ open [f]world(pub, key_clsfy);
    pk_init(&context);
    //@ close [f]world(pub, key_clsfy);
    set_public_key(&context, key);
    //@ open [f]world(pub, key_clsfy);
    /*@ assert pk_context_with_key(&context, pk_public,
                                   ?principal, ?count, RSA_BIT_KEY_SIZE); @*/
    //@ assert col || principal == principal2;
    //@ assert col || count == count2;

    // Encryption
    //@ open item(payload, pay, pub);
    //@ assert [_]item_constraints(pay, ?pay_cs, pub);
    if (payload->size > RSA_KEY_SIZE)
      abort_crypto_lib("Asymmetric encryption failed: incorrect sizes");
    void *random_state = nonces_expose_state();
    //@ close random_state_predicate(havege_state_initialized);
    /*@ produce_function_pointer_chunk random_function(
                      asym_enc_havege_random_stub)
                     (havege_state_initialized)(state, out, len) { call(); } @*/
    //@ open principal(principal1, count1);
    if(pk_encrypt(&context, payload->content, (unsigned int) payload->size,
                  output, &olen, MAX_PACKAGE_SIZE,
                  asym_enc_havege_random_stub, random_state) != 0)
      abort_crypto_lib("Encryption failed");
    //@ close principal(principal1, count1 + 1);
    //@ open cryptogram(output, ?enc_length, ?enc_cs, ?enc_cg);
    //@ assert enc_cg == cg_asym_encrypted(principal, count, pay_cs, ?ent);
    //@ assert u_integer(&olen, enc_length);
    //@ assert enc_length > 0 &*& enc_length < MAX_PACKAGE_SIZE;
    //@ assert enc_length > 0 &*& enc_length <= RSA_SERIALIZED_KEY_SIZE;
    nonces_hide_state(random_state);
    //@ pk_release_context_with_key(&context);
    pk_free(&context);
    //@ open pk_context(&context);
    //@ close [f]world(pub, key_clsfy);

    // Create item
    result->size = TAG_LENGTH + (int) olen;
    result->content = malloc(result->size);
    if (result->content == 0) {abort_crypto_lib("Malloc failed");}
    write_tag(result->content, TAG_ASYMMETRIC_ENC);
    //@ assert result->content |-> ?cont &*& result->size |-> ?size;
    if (olen < MINIMAL_STRING_SIZE) {abort_crypto_lib("Asymmetric encryption failed: to small");}
    memcpy(result->content + TAG_LENGTH, output, olen);
    //@ assert chars(cont, TAG_LENGTH, ?cs_tag);
    //@ public_chars(cont, TAG_LENGTH);
    //@ chars_to_secret_crypto_chars(cont, TAG_LENGTH);
    //@ assert cs_tag == full_tag(TAG_ASYMMETRIC_ENC);
    //@ crypto_chars_join(cont);

    //@ item enc = asymmetric_encrypted_item(principal, count, some(pay), ent);
    //@ list<char> cs = append(cs_tag, enc_cs);
    //@ WELL_FORMED(cs_tag, enc_cs, TAG_ASYMMETRIC_ENC)
    //@ close ic_parts(enc)(cs_tag, enc_cs);
    //@ close ic_cg(enc)(enc_cs, enc_cg);
    /*@ if (col)
      {
        crypto_chars_to_chars(cont, size);
        public_chars(cont, size);
        chars_to_secret_crypto_chars(cont, size);
        public_generated_split(polarssl_pub(pub), cs, TAG_LENGTH);
      }
    @*/
    //@ well_formed_item_constraints(pay, enc);
    //@ close item_constraints(enc, cs, pub);
    //@ leak item_constraints(enc, cs, pub);
    //@ close item(result, enc, pub);
    zeroize(output, (int) olen);
    //@ chars_join(output);
    //@ close item(payload, pay, pub);
  }

  debug_print("ENCRYPTING RESULT:\n");
  print_item(result);

  return result;
}
Ejemplo n.º 20
0
int main( int argc, char *argv[] )
{
    FILE *f;
    int ret = 1;
    pk_context pk;
    entropy_context entropy;
    ctr_drbg_context ctr_drbg;
    unsigned char hash[20];
    unsigned char buf[POLARSSL_MPI_MAX_SIZE];
    char filename[512];
    const char *pers = "pk_sign";
    size_t olen = 0;

    entropy_init( &entropy );
    pk_init( &pk );

    if( argc != 3 )
    {
        polarssl_printf( "usage: pk_sign <key_file> <filename>\n" );

#if defined(_WIN32)
        polarssl_printf( "\n" );
#endif

        goto exit;
    }

    polarssl_printf( "\n  . Seeding the random number generator..." );
    fflush( stdout );

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

    polarssl_printf( "\n  . Reading private key from '%s'", argv[1] );
    fflush( stdout );

    if( ( ret = pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 )
    {
        ret = 1;
        polarssl_printf( " failed\n  ! Could not open '%s'\n", argv[1] );
        goto exit;
    }

    /*
     * Compute the SHA-1 hash of the input file,
     * then calculate the signature of the hash.
     */
    polarssl_printf( "\n  . Generating the SHA-1 signature" );
    fflush( stdout );

    if( ( ret = sha1_file( argv[2], hash ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! Could not open or read %s\n\n", argv[2] );
        goto exit;
    }

    if( ( ret = pk_sign( &pk, POLARSSL_MD_SHA1, hash, 0, buf, &olen,
                         ctr_drbg_random, &ctr_drbg ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! pk_sign returned -0x%04x\n", -ret );
        goto exit;
    }

    /*
     * Write the signature into <filename>-sig.txt
     */
    snprintf( filename, sizeof(filename), "%s.sig", argv[2] );

    if( ( f = fopen( filename, "wb+" ) ) == NULL )
    {
        ret = 1;
        polarssl_printf( " failed\n  ! Could not create %s\n\n", filename );
        goto exit;
    }

    if( fwrite( buf, 1, olen, f ) != olen )
    {
        polarssl_printf( "failed\n  ! fwrite failed\n\n" );
        goto exit;
    }

    fclose( f );

    polarssl_printf( "\n  . Done (created \"%s\")\n\n", filename );

exit:
    pk_free( &pk );
    ctr_drbg_free( &ctr_drbg );
    entropy_free( &entropy );

#if defined(POLARSSL_ERROR_C)
    polarssl_strerror( ret, (char *) buf, sizeof(buf) );
    polarssl_printf( "  !  Last error was: %s\n", buf );
#endif

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

    return( ret );
}
Ejemplo n.º 21
0
int main( int argc, char *argv[] )
{
    int ret = 0, server_fd;
    unsigned char buf[1024];
    entropy_context entropy;
    ctr_drbg_context ctr_drbg;
    ssl_context ssl;
    x509_crt cacert;
    x509_crt clicert;
    pk_context pkey;
    int i, j;
    int flags, verify = 0;
    char *p, *q;
    const char *pers = "cert_app";

    /*
     * Set to sane values
     */
    server_fd = 0;
    x509_crt_init( &cacert );
    x509_crt_init( &clicert );
    pk_init( &pkey );

    if( argc == 0 )
    {
    usage:
        printf( USAGE );
        goto exit;
    }

    opt.mode                = DFL_MODE;
    opt.filename            = DFL_FILENAME;
    opt.ca_file             = DFL_CA_FILE;
    opt.ca_path             = DFL_CA_PATH;
    opt.server_name         = DFL_SERVER_NAME;
    opt.server_port         = DFL_SERVER_PORT;
    opt.debug_level         = DFL_DEBUG_LEVEL;
    opt.permissive          = DFL_PERMISSIVE;

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

        for( j = 0; p + j < q; j++ )
        {
            if( argv[i][j] >= 'A' && argv[i][j] <= 'Z' )
                argv[i][j] |= 0x20;
        }

        if( strcmp( p, "mode" ) == 0 )
        {
            if( strcmp( q, "file" ) == 0 )
                opt.mode = MODE_FILE;
            else if( strcmp( q, "ssl" ) == 0 )
                opt.mode = MODE_SSL;
            else
                goto usage;
        }
        else if( strcmp( p, "filename" ) == 0 )
            opt.filename = q;
        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, "server_name" ) == 0 )
            opt.server_name = 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, "permissive" ) == 0 )
        {
            opt.permissive = atoi( q );
            if( opt.permissive < 0 || opt.permissive > 1 )
                goto usage;
        }
        else
            goto usage;
    }

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

    if( strlen( opt.ca_path ) )
    {
        ret = x509_crt_parse_path( &cacert, opt.ca_path );
        verify = 1;
    }
    else if( strlen( opt.ca_file ) )
    {
        ret = x509_crt_parse_file( &cacert, opt.ca_file );
        verify = 1;
    }

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

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

    if( opt.mode == MODE_FILE )
    {
        x509_crt crt;
        x509_crt *cur = &crt;
        x509_crt_init( &crt );

        /*
         * 1.1. Load the certificate(s)
         */
        printf( "\n  . Loading the certificate(s) ..." );
        fflush( stdout );

        ret = x509_crt_parse_file( &crt, opt.filename );

        if( ret < 0 )
        {
            printf( " failed\n  !  x509_crt_parse_file returned %d\n\n", ret );
            x509_crt_free( &crt );
            goto exit;
        }

        if( opt.permissive == 0 && ret > 0 )
        {
            printf( " failed\n  !  x509_crt_parse failed to parse %d certificates\n\n", ret );
            x509_crt_free( &crt );
            goto exit;
        }

        printf( " ok\n" );

        /*
         * 1.2 Print the certificate(s)
         */
        while( cur != NULL )
        {
            printf( "  . Peer certificate information    ...\n" );
            ret = x509_crt_info( (char *) buf, sizeof( buf ) - 1, "      ",
                                 cur );
            if( ret == -1 )
            {
                printf( " failed\n  !  x509_crt_info returned %d\n\n", ret );
                x509_crt_free( &crt );
                goto exit;
            }

            printf( "%s\n", buf );

            cur = cur->next;
        }

        /*
         * 1.3 Verify the certificate
         */
        if( verify )
        {
            printf( "  . Verifying X.509 certificate..." );

            if( ( ret = x509_crt_verify( &crt, &cacert, NULL, NULL, &flags,
                                         my_verify, NULL ) ) != 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" );
        }

        x509_crt_free( &crt );
    }
    else if( opt.mode == MODE_SSL )
    {
        /*
         * 1. 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 %d\n", ret );
            goto exit;
        }

        printf( " ok\n" );

        /*
         * 2. Start the connection
         */
        printf( "  . SSL connection to tcp/%s/%-4d...", opt.server_name,
                                                        opt.server_port );
        fflush( stdout );

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

        /*
         * 3. Setup stuff
         */
        if( ( ret = ssl_init( &ssl ) ) != 0 )
        {
            printf( " failed\n  ! ssl_init returned %d\n\n", ret );
            goto exit;
        }

        ssl_set_endpoint( &ssl, SSL_IS_CLIENT );
        if( verify )
        {
            ssl_set_authmode( &ssl, SSL_VERIFY_REQUIRED );
            ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name );
            ssl_set_verify( &ssl, my_verify, NULL );
        }
        else
            ssl_set_authmode( &ssl, SSL_VERIFY_NONE );

        ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg );
        ssl_set_dbg( &ssl, my_debug, stdout );
        ssl_set_bio( &ssl, net_recv, &server_fd,
                net_send, &server_fd );

        ssl_set_own_cert( &ssl, &clicert, &pkey );

#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
        ssl_set_hostname( &ssl, opt.server_name );
#endif

        /*
         * 4. Handshake
         */
        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 %d\n\n", ret );
                ssl_free( &ssl );
                goto exit;
            }
        }

        printf( " ok\n" );

        /*
         * 5. Print the certificate
         */
        printf( "  . Peer certificate information    ...\n" );
        ret = x509_crt_info( (char *) buf, sizeof( buf ) - 1, "      ",
                             ssl.session->peer_cert );
        if( ret == -1 )
        {
            printf( " failed\n  !  x509_crt_info returned %d\n\n", ret );
            ssl_free( &ssl );
            goto exit;
        }

        printf( "%s\n", buf );

        ssl_close_notify( &ssl );
        ssl_free( &ssl );
    }
    else
        goto usage;

exit:

    if( server_fd )
        net_close( server_fd );
    x509_crt_free( &cacert );
    x509_crt_free( &clicert );
    pk_free( &pkey );
    entropy_free( &entropy );

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

    return( ret );
}
Ejemplo n.º 22
0
void SSL_CTX_free(SSL_CTX *ctx) {
  x509_crt_free(&ctx->cert);
  x509_crt_free(&ctx->CA_cert);
  pk_free(&ctx->pk);
  free(ctx);
}
Ejemplo n.º 23
0
int main( int argc, const char *argv[] )
{
    /* Client and server declarations. */
    int ret;
    int len;
#if SOCKET_COMMUNICATION
    int listen_fd = -1;
    int client_fd = -1;
    int server_fd = -1;
#endif
    unsigned char buf[1024];
    /* Handshake step counter */
    size_t step = 1;
    int flags;

    ssl_context s_ssl, c_ssl;
    x509_crt srvcert;
    pk_context pkey;
#if defined(POLARSSL_SSL_CACHE_C)
    ssl_cache_context cache;
#endif

    if( argc == 3)
    {
        packet_in_num = atoi(argv[1]);
        packet_in_file = argv[2];
    }
    else if( argc != 1)
    {
        usage(argv[0]);
        exit(1);
    }

    /* Server init */
    memset( &s_ssl, 0, sizeof( ssl_context ) );
#if defined(POLARSSL_SSL_CACHE_C)
    ssl_cache_init( &cache );
#endif
    x509_crt_init( &srvcert );
    pk_init( &pkey );

    /* Client init */
    memset( &c_ssl, 0, sizeof( ssl_context ) );
    /*x509_crt_init( &cacert );*/

#if defined(POLARSSL_DEBUG_C)
    debug_set_threshold( DEBUG_LEVEL );
#endif

    /*
     * Server:
     * Load the certificates and private RSA key
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Loading the server cert. and key..." );
        fflush( stdout );
    }

    /*
     * This demonstration program uses embedded test certificates.
     * Instead, you may want to use x509_crt_parse_file() to read the
     * server and CA certificates, as well as pk_parse_keyfile().
     */
    ret = x509_crt_parse( &srvcert, (const unsigned char *) test_srv_crt,
                          strlen( test_srv_crt ) );
    if( ret != 0 )
    {
        printf( " failed\n  !  x509_crt_parse returned %d\n\n", ret );
        goto exit;
    }

    ret = x509_crt_parse( &srvcert, (const unsigned char *) test_ca_list,
                          strlen( test_ca_list ) );
    if( ret != 0 )
    {
        polarssl_printf( " failed\n  !  x509_crt_parse returned %d\n\n", ret );
        goto exit;
    }

    ret =  pk_parse_key( &pkey, (const unsigned char *) test_srv_key,
                         strlen( test_srv_key ), NULL, 0 );
    if( ret != 0 )
    {
        printf( " failed\n  !  pk_parse_key returned %d\n\n", ret );
        goto exit;
    }

    if( packet_in_num == 0 )
    {
        printf( " ok\n" );
    }

    /*
     * Server:
     * Setup stuff
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Server: Setting up the SSL data...." );
        fflush( stdout );
    }

    if( ( ret = ssl_init( &s_ssl ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! ssl_init returned %d\n\n", ret );
        goto exit;
    }

    ssl_set_endpoint( &s_ssl, SSL_IS_SERVER );
    ssl_set_authmode( &s_ssl, SSL_VERIFY_NONE );

    /* SSLv3 is deprecated, set minimum to TLS 1.0 */
    ssl_set_min_version( &s_ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1 );
    /* RC4 is deprecated, disable it */
    ssl_set_arc4_support( &s_ssl, SSL_ARC4_DISABLED );

    ssl_set_rng( &s_ssl, ctr_drbg_deterministic, NULL );
    ssl_set_dbg( &s_ssl, my_debug, stdout );

#if defined(POLARSSL_SSL_CACHE_C)
    ssl_set_session_cache( &s_ssl, ssl_cache_get, &cache,
                           ssl_cache_set, &cache );
#endif

    ssl_set_ca_chain( &s_ssl, srvcert.next, NULL, NULL );
    if( ( ret = ssl_set_own_cert( &s_ssl, &srvcert, &pkey ) ) != 0 )
    {
        printf( " failed\n  ! ssl_set_own_cert returned %d\n\n", ret );
        goto exit;
    }

    if( packet_in_num == 0 )
    {
        printf( " ok\n" );
    }

    ssl_session_reset( &s_ssl );

#if SOCKET_COMMUNICATION
    /*
     * Server:
     * Setup the listening TCP socket
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Bind on https://localhost:%d/ ...", SERVER_PORT );
        fflush( stdout );
    }

    if( ( ret = net_bind( &listen_fd, NULL, SERVER_PORT ) ) != 0 )
    {
        printf( " failed\n  ! net_bind returned %d\n\n", ret );
        goto exit;
    }

    if( packet_in_num == 0 )
    {
        printf( " ok\n" );
    }

    /*
     * Client:
     * Start the connection
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Connecting to tcp/%s/%d...", SERVER_NAME, SERVER_PORT );
        fflush( stdout );
    }

    if( ( ret = net_connect( &server_fd, SERVER_NAME,
                             SERVER_PORT ) ) != 0 )
    {
        printf( " failed\n  ! net_connect returned %d\n\n", ret );
        goto exit;
    }

    if( packet_in_num == 0 )
    {
        printf( " ok\n" );
    }

    /*
     * Server:
     * Start listening for client connections
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Waiting for a remote connection ..." );
        fflush( stdout );
    }

    /*
     * Server:
     * Accept client connection (socket is set non-blocking in
     * library/net.c)
     */
    if( ( ret = net_accept( listen_fd, &client_fd,
                            NULL ) ) != 0 )
    {
        printf( " failed\n  ! net_accept returned %d\n\n", ret );
        goto exit;
    }

    if( packet_in_num == 0 )
    {
        printf( " ok\n" );
    }

    ssl_set_bio( &s_ssl, recv_custom, &client_fd, send_custom, &client_fd );
#else
    ssl_set_bio( &s_ssl, func_server_recv_buf, NULL, func_server_send_buf, NULL );
#endif

    /*
     * Client:
     * Setup stuff
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Client: Setting up the SSL/TLS structure..." );
        fflush( stdout );
    }

    if( ( ret = ssl_init( &c_ssl ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! ssl_init returned %d\n\n", ret );
        goto exit;
    }

    if( packet_in_num == 0 )
    {
        polarssl_printf( " ok\n" );
    }

    ssl_set_endpoint( &c_ssl, SSL_IS_CLIENT );
    /* OPTIONAL is not optimal for security,
     * but makes interop easier in this simplified example */
    ssl_set_authmode( &c_ssl, SSL_VERIFY_OPTIONAL );
    /* NONE permits man-in-the-middle attacks. */
    /*ssl_set_authmode( &c_ssl, VERIFY_NONE );*/
    /*ssl_set_authmode( &c_ssl, SSL_VERIFY_REQUIRED );*/
    ssl_set_ca_chain( &c_ssl, &srvcert, NULL, "PolarSSL Server 1" );

    /* SSLv3 is deprecated, set minimum to TLS 1.0 */
    ssl_set_min_version( &c_ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1 );
    /* RC4 is deprecated, disable it */
    ssl_set_arc4_support( &c_ssl, SSL_ARC4_DISABLED );

    ssl_set_rng( &c_ssl, ctr_drbg_deterministic, NULL );
    ssl_set_dbg( &c_ssl, my_debug, stdout );

    if( ( ret = ssl_set_hostname( &c_ssl, "mbed TLS Server 1" ) ) != 0 )
    {
        printf( " failed\n  ! ssl_set_hostname returned %d\n\n", ret );
        goto exit;
    }

#if SOCKET_COMMUNICATION
    ssl_set_bio( &c_ssl, recv_custom, &server_fd, send_custom, &server_fd );
#else
    ssl_set_bio( &c_ssl, func_client_recv_buf, NULL, func_client_send_buf,  NULL );
#endif

    if( packet_in_num == 0 )
    {
        printf( "  . Performing the SSL/TLS handshake...\n" );
        fflush( stdout );
    }

    /*
     * The following number of steps are hardcoded to ensure
     * that the client and server complete the handshake without
     * waiting infinitely for the other side to send data.
     *
     *                     1  2  3  4  5  6  7  8  9
     */
    int client_steps[] = { 2, 1, 1, 1, 4, 2, 1, 1, 3 };
    int server_steps[] = { 3, 1, 1, 3, 2, 1, 2, 1, 2 };

    do {
        /*
         * Client:
         * Handshake step
         */
        int i;
        int no_steps;

        if( c_ssl.state == SSL_HANDSHAKE_OVER ) {
            no_steps = 0;
        } else {
            no_steps = client_steps[step - 1];
        }

        for (i = 0; i < no_steps; i++) {
            if(  ( ret = ssl_handshake_step( &c_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;
                }
            }
        }

        if( packet_in_num == 0 )
        {
            printf( "--- client handshake step %zd ok\n", step );
        }

        /*
         * Server:
         * Handshake step
         */
        if( s_ssl.state == SSL_HANDSHAKE_OVER ) {
            printf("over\n");
            no_steps = 0;
        } else {
            no_steps = server_steps[step - 1];
        }

        for (i = 0; i < no_steps; i++) {
            if(  ( ret = ssl_handshake_step( &s_ssl ) ) != 0 )
            {
                if(  ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
                {
                    printf( " failed\n  ! ssl_handshake returned %d\n\n", ret );
                    goto exit;
                }
            }
        }

        if( packet_in_num == 0 )
        {
            printf( "--- server handshake step %zd ok\n", step );
        }

        step++;
    } while( ((c_ssl.state != SSL_HANDSHAKE_OVER)
              || (s_ssl.state != SSL_HANDSHAKE_OVER))
             && (step <= MAX_HANDSHAKE_STEPS) );

    if( packet_in_num == 0 )
    {
        printf( "c_ssl.state: %d\n", c_ssl.state != SSL_HANDSHAKE_OVER );
        printf( "s_ssl.state: %d\n", s_ssl.state != SSL_HANDSHAKE_OVER );
    }

    /*
     * Client:
     * Verify the server certificate
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Verifying peer X.509 certificate..." );
    }

    /* In real life, we probably want to bail out when ret != 0 */
    if( ( flags = ssl_get_verify_result( &c_ssl ) ) != 0 )
    {
        char vrfy_buf[512];

        printf( " failed\n" );

        x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", flags );

        printf( "%s\n", vrfy_buf );
    }
    else if( packet_in_num == 0 )
    {
        printf( " ok\n" );
    }

    /*
     * Client:
     * Write the GET request
     */
    if( packet_in_num == 0 )
    {
        printf( "  > Write to server:" );
        fflush( stdout );
    }

    len = sprintf( (char *) buf, GET_REQUEST );

    while( ( ret = ssl_write( &c_ssl, buf, len ) ) <= 0 )
    {
        if( ret !=POLARSSL_ERR_NET_WANT_READ && ret !=POLARSSL_ERR_NET_WANT_WRITE )
        {
            printf( " failed\n  ! ssl_write returned %d\n\n", ret );
            goto exit;
        }
    }

    len = ret;
    if( packet_in_num == 0 )
    {
        printf( " %d bytes written\n\n%s", len, (char *) buf );
    }

    /*
     * Server:
     * Read the HTTP Request
     */
    if( packet_in_num == 0 )
    {
        printf( "  < Read from client:" );
        fflush( stdout );
    }

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

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

        if( ret <= 0 )
        {
            switch( ret )
            {
            case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY:
                printf( " connection was closed gracefully\n" );
                break;

            case POLARSSL_ERR_NET_CONN_RESET:
                printf( " connection was reset by peer\n" );
                break;

            default:
                printf( " ssl_read returned -0x%x\n", -ret );
                break;
            }

            break;
        }

        len = ret;
        if( packet_in_num == 0 )
        {
            printf( " %d bytes read\n\n%s", len, (char *) buf );
        }

        if( ret > 0 )
            break;
    }
    while( 1 );

    /*
     * Server:
     * Write the 200 Response
     */
    if( packet_in_num == 0 )
    {
        printf( "  > Write to client:" );
        fflush( stdout );
    }

    len = sprintf( (char *) buf, HTTP_RESPONSE,
                   ssl_get_ciphersuite( &s_ssl ) );

    while( ( ret = ssl_write( &s_ssl, buf, len ) ) <= 0 )
    {
        if( ret == POLARSSL_ERR_NET_CONN_RESET )
        {
            printf( " failed\n  ! peer closed the connection\n\n" );
            goto exit;
        }

        if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
        {
            printf( " failed\n  ! ssl_write returned %d\n\n", ret );
            goto exit;
        }
    }

    len = ret;
    if( packet_in_num == 0 )
    {
        printf( " %d bytes written\n\n%s\n", len, (char *) buf );
    }

    /*
     * Client:
     * Read the HTTP response
     */
    if( packet_in_num == 0 )
    {
        printf( "  < Read from server:" );
        fflush( stdout );
    }

    do
    {
        len = sizeof( buf ) - 1;
        memset( buf, 0, sizeof( buf ) );
        ret = ssl_read( &c_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 )
        {
            ret = 0;
            break;
        }

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

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

        len = ret;
        if( packet_in_num == 0 )
        {
            printf( " %d bytes read\n\n%s", len, (char *) buf );
        }

        /*
         * Server:
         * Client read response. Close connection.
         */
        if ( packet_in_num == 0 )
        {
            printf( "  . Closing the connection..." );
            fflush( stdout );
        }

        while( ( ret = ssl_close_notify( &s_ssl ) ) < 0 )
        {
            if( ret != POLARSSL_ERR_NET_WANT_READ &&
                    ret != POLARSSL_ERR_NET_WANT_WRITE )
            {
                printf( " failed\n  ! ssl_close_notify returned %d\n\n", ret );
                goto exit;
            }
        }

        if( packet_in_num == 0 )
        {
            printf( " ok\n" );
        }
    }
    while( 1 );

    /*
     * Client:
     * Close connection.
     */
    if( packet_in_num == 0 )
    {
        printf( "  . Closing the connection..." );
        fflush( stdout );
    }

    ssl_close_notify( &c_ssl );

    if( packet_in_num == 0 )
    {
        printf( " ok\n" );
    }

    /*
     * Server:
     * We do not have multiple clients and therefore do not goto reset.
     */
    /*ret = 0;*/
    /*goto reset;*/

exit:

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

#if SOCKET_COMMUNICATION
    if ( client_fd != 1 )
        net_close( client_fd );
    if( server_fd != -1 )
        net_close( server_fd );
    if ( listen_fd != 1 )
        net_close( listen_fd );
#endif

    x509_crt_free( &srvcert );
    pk_free( &pkey );
    ssl_free( &s_ssl );
    ssl_free( &c_ssl );
#if defined(POLARSSL_SSL_CACHE_C)
    ssl_cache_free( &cache );
#endif

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

    return( ret );
}
Ejemplo n.º 24
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);
}
Ejemplo n.º 25
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);
}
Ejemplo n.º 26
0
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
	//misc vars
	char currentpath[MAX_PATH] = {0};
	//vars for getting public key from exe
	unsigned char *pubrsakey = NULL;
	int pubkeylen = 0;	
	//vars for taking the screenshot
	unsigned char *finalbmpfile = NULL;
	unsigned char *finalcompressedbmpfile = NULL;
	int finalcompressedbmpfilelen = 0;
	int finalbmpfilesize = 0;
	//vars for data encryption
	pk_context pk_ctx;
	char *keypersonalisation = "5T+qDlP1=R1ek?GLqi|=)1O(niSimHBx|2\5QE.DN<7W\"]I@:?uSa#}txXN<9oG6";
	char *ivpersonalisation = "J0eeYYCW.`6m;I5[v4|]0NDe1Hx)Co8D u]~9ZC\"x6AESc=a\\/W-e7d1bnMwq,z=]";	
	unsigned char *aeskey = NULL;
	unsigned char *aesiv = NULL;
	unsigned char *encrypteddata = NULL;
	int encrypteddatalen = 0;
	unsigned char *pubkeyencrypteddata;
	unsigned int pubkeyencrypteddatalen = 0;
	unsigned char keydata[48] = {0};
	//vars for hmac
	char *hmackeypersonalisation = "UGY624Z078'm.34\"|TSUOu\\M4}r!ammvFekes:%48=RmaA\\?SC.UTi8zB)A1a[P:";
	unsigned char *hmackey = NULL;
	unsigned char hmacoutput[64] = {0};
	//vars for writing to file
	DWORD dwBytesWritten = 0;
	HANDLE hFile = NULL;
	
	outputerror(DBG_INFO,"%s\n","main::started");
	/* get public key*/
	GetModuleFileName(NULL,&currentpath[0],sizeof(currentpath));
	pubrsakey = getpublickeyfromself(&currentpath[0],&pubkeylen);
	if(pubrsakey == NULL){
		outputerror(DBG_ERROR,"%s\n","main::failed to get public key");
		SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0])));
		exit(1);
	}

	SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0])));
	/* take screenshot */
	if(takescreenshot(&finalbmpfile,&finalbmpfilesize) == 1){
		outputerror(DBG_ERROR,"%s\n","main::failed to take screenshot");		
		SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0])));
		zfree(finalbmpfile);
		exit(1);
	}

	/* Main logic code
		generate aes key
		generate aes iv
		generate hmac key
		rsa encrypt(aeskey,aesiv)
		write encrypted rsa length
		write encrypted rsa blob
		encrypt screenshot
		write encrypted hmac key
		hmac(encrypted screenshot)
		write hmac
		write screenshot
		send screenshot
		delete screenshot

		In case you are wondering why locally save and delete,
		so that we don't loose screenshots if the sending fails.

	*/
	aeskey = generatekey(keypersonalisation,256);
	aesiv = generatekey(ivpersonalisation,128);
	hmackey = generatekey(hmackeypersonalisation,256);
	memcpy_s(keydata,48,aeskey,32);
	memcpy_s(keydata+32,48,aesiv,16);

	/* get and parse public key */
	pk_ctx = getpubkeycontext(pubrsakey,pubkeylen);
	if(pk_get_len(&pk_ctx) == 0){
		outputerror(DBG_ERROR,"%s\n","main::failed to parse public key");
		pk_free(&pk_ctx);		
		SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0])));
		zfree(finalbmpfile);
		exit(1);
	}
	/* encrypt aes key and iv and write to file */
	pubkeyencrypteddatalen = pk_get_len(&pk_ctx);
	pubkeyencrypteddata = (unsigned char *)malloc(pubkeyencrypteddatalen);
	SecureZeroMemory(pubkeyencrypteddata,pubkeyencrypteddatalen);
	pubkeyencrypteddata = rsacrypt(&pk_ctx,keydata,48);
	if(pubkeyencrypteddata == NULL){
		outputerror(DBG_ERROR,"%s\n","main::failed to encrypt aes key + aes iv");
		pk_free(&pk_ctx);
		SecureZeroMemory(aeskey,32);
		SecureZeroMemory(aesiv,16);		
		SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0])));
		zfree(finalbmpfile);
		exit(1);
	}
	hFile = CreateFile("screen.enc", GENERIC_WRITE, 0, NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	WriteFile(hFile,(char *)&pubkeyencrypteddatalen,4,&dwBytesWritten,NULL);
	WriteFile(hFile,pubkeyencrypteddata,pubkeyencrypteddatalen,&dwBytesWritten,NULL);
	/* compress screenshot */
	outputerror(DBG_INFO,"%s\n","main::compressing screenshot");
	finalcompressedbmpfilelen = compressdata(finalbmpfile,finalbmpfilesize,&finalcompressedbmpfile);
	if(finalcompressedbmpfilelen == 0){
		outputerror(DBG_ERROR,"%s\n","main::failed to compress final bmp file");
		pk_free(&pk_ctx);
		SecureZeroMemory(aeskey,32);
		SecureZeroMemory(aesiv,16);
		SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0])));
		zfree(finalbmpfile);
		zfree(finalcompressedbmpfile);
		exit(1);
	}
	SecureZeroMemory(finalbmpfile,finalbmpfilesize);
	/* encrypt screenshot */
	encrypteddata = encryptaes(aeskey,256,aesiv,finalcompressedbmpfile,finalcompressedbmpfilelen,&encrypteddatalen);
	if(encrypteddata == NULL){
		outputerror(DBG_ERROR,"%s\n","main::failed to encrypt the actual screenshot");
		pk_free(&pk_ctx);
		SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0])));
		zfree(finalbmpfile);
		exit(1);
	}
	/* encrypt hmac key and write to file*/
	SecureZeroMemory(pubkeyencrypteddata,pubkeyencrypteddatalen);
	pubkeyencrypteddata = rsacrypt(&pk_ctx,hmackey,32);
	if(pubkeyencrypteddata == NULL){
		outputerror(DBG_ERROR,"%s\n","main::failed to encrypt hmac key");
		pk_free(&pk_ctx);
		SecureZeroMemory(aeskey,32);
		SecureZeroMemory(aesiv,16);
		SecureZeroMemory(hmackey,32);
		SecureZeroMemory(finalbmpfile,finalbmpfilesize);
		SecureZeroMemory(currentpath,(sizeof(currentpath)/sizeof(currentpath[0])));
		exit(1);
	}
	WriteFile(hFile,pubkeyencrypteddata,pubkeyencrypteddatalen,&dwBytesWritten,NULL);
	/* calculate hmac(encrypteddata) and write to file */
	sha512_hmac(hmackey,32,encrypteddata,encrypteddatalen,hmacoutput,0);
	WriteFile(hFile,hmacoutput,64,&dwBytesWritten,NULL);
	/* write encrypted screenshot to file */
	WriteFile(hFile,encrypteddata,encrypteddatalen,&dwBytesWritten,NULL);
	CloseHandle(hFile);

	/* cleanup */	
	pk_free(&pk_ctx);
	SecureZeroMemory(finalbmpfile,finalbmpfilesize);
	SecureZeroMemory(keydata,48);
	SecureZeroMemory(aeskey,32);
	SecureZeroMemory(aesiv,16);
	SecureZeroMemory(hmackey,32);
	SecureZeroMemory(finalbmpfile,finalbmpfilesize);
	free(finalbmpfile);
	free(finalcompressedbmpfile);
	free(aeskey);
	free(aesiv);
	free(hmackey);
	free(pubrsakey);
	free(encrypteddata);
	free(pubkeyencrypteddata);
	outputerror(DBG_INFO,"%s\n","main::finished");

	/* now we send the file to our server if it works, we delete the file */
	if (uploadscreenshot(UPLOAD_SERVER, "screen.enc") == 1){
		DeleteFile("screen.enc");
	}
	return 0;
}
Ejemplo n.º 27
0
cPublicKey::~cPublicKey()
{
	pk_free(&m_Pk);
}
Ejemplo n.º 28
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 );
}
Ejemplo n.º 29
0
static CURLcode
polarssl_connect_step1(struct connectdata *conn,
                       int sockindex)
{
  struct Curl_easy *data = conn->data;
  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
  const char *capath = SSL_CONN_CONFIG(CApath);
  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
    conn->host.name;
  const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
  int ret = -1;
  char errorbuf[128];
  errorbuf[0]=0;

  /* PolarSSL only supports SSLv3 and TLSv1 */
  if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
    failf(data, "PolarSSL does not support SSLv2");
    return CURLE_SSL_CONNECT_ERROR;
  }

#ifdef THREADING_SUPPORT
  entropy_init_mutex(&entropy);

  if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func_mutex, &entropy,
                          NULL, 0)) != 0) {
    error_strerror(ret, errorbuf, sizeof(errorbuf));
    failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
          -ret, errorbuf);
  }
#else
  entropy_init(&BACKEND->entropy);

  if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func, &BACKEND->entropy,
                          NULL, 0)) != 0) {
    error_strerror(ret, errorbuf, sizeof(errorbuf));
    failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
          -ret, errorbuf);
  }
#endif /* THREADING_SUPPORT */

  /* Load the trusted CA */
  memset(&BACKEND->cacert, 0, sizeof(x509_crt));

  if(SSL_CONN_CONFIG(CAfile)) {
    ret = x509_crt_parse_file(&BACKEND->cacert,
                              SSL_CONN_CONFIG(CAfile));

    if(ret<0) {
      error_strerror(ret, errorbuf, sizeof(errorbuf));
      failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s",
            SSL_CONN_CONFIG(CAfile), -ret, errorbuf);

      if(SSL_CONN_CONFIG(verifypeer))
        return CURLE_SSL_CACERT_BADFILE;
    }
  }

  if(capath) {
    ret = x509_crt_parse_path(&BACKEND->cacert, capath);

    if(ret<0) {
      error_strerror(ret, errorbuf, sizeof(errorbuf));
      failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s",
            capath, -ret, errorbuf);

      if(SSL_CONN_CONFIG(verifypeer))
        return CURLE_SSL_CACERT_BADFILE;
    }
  }

  /* Load the client certificate */
  memset(&BACKEND->clicert, 0, sizeof(x509_crt));

  if(SSL_SET_OPTION(cert)) {
    ret = x509_crt_parse_file(&BACKEND->clicert,
                              SSL_SET_OPTION(cert));

    if(ret) {
      error_strerror(ret, errorbuf, sizeof(errorbuf));
      failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s",
            SSL_SET_OPTION(cert), -ret, errorbuf);

      return CURLE_SSL_CERTPROBLEM;
    }
  }

  /* Load the client private key */
  if(SSL_SET_OPTION(key)) {
    pk_context pk;
    pk_init(&pk);
    ret = pk_parse_keyfile(&pk, SSL_SET_OPTION(key),
                           SSL_SET_OPTION(key_passwd));
    if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA))
      ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
    if(ret == 0)
      rsa_copy(&BACKEND->rsa, pk_rsa(pk));
    else
      rsa_free(&BACKEND->rsa);
    pk_free(&pk);

    if(ret) {
      error_strerror(ret, errorbuf, sizeof(errorbuf));
      failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s",
            SSL_SET_OPTION(key), -ret, errorbuf);

      return CURLE_SSL_CERTPROBLEM;
    }
  }

  /* Load the CRL */
  memset(&BACKEND->crl, 0, sizeof(x509_crl));

  if(SSL_SET_OPTION(CRLfile)) {
    ret = x509_crl_parse_file(&BACKEND->crl,
                              SSL_SET_OPTION(CRLfile));

    if(ret) {
      error_strerror(ret, errorbuf, sizeof(errorbuf));
      failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s",
            SSL_SET_OPTION(CRLfile), -ret, errorbuf);

      return CURLE_SSL_CRL_BADFILE;
    }
  }

  infof(data, "PolarSSL: Connecting to %s:%d\n", hostname, port);

  if(ssl_init(&BACKEND->ssl)) {
    failf(data, "PolarSSL: ssl_init failed");
    return CURLE_SSL_CONNECT_ERROR;
  }

  switch(SSL_CONN_CONFIG(version)) {
  case CURL_SSLVERSION_DEFAULT:
  case CURL_SSLVERSION_TLSv1:
    ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
                        SSL_MINOR_VERSION_1);
    break;
  case CURL_SSLVERSION_SSLv3:
    ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
                        SSL_MINOR_VERSION_0);
    ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
                        SSL_MINOR_VERSION_0);
    infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n");
    break;
  case CURL_SSLVERSION_TLSv1_0:
  case CURL_SSLVERSION_TLSv1_1:
  case CURL_SSLVERSION_TLSv1_2:
  case CURL_SSLVERSION_TLSv1_3:
    {
      CURLcode result = set_ssl_version_min_max(conn, sockindex);
      if(result != CURLE_OK)
        return result;
      break;
    }
  default:
    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
    return CURLE_SSL_CONNECT_ERROR;
  }

  ssl_set_endpoint(&BACKEND->ssl, SSL_IS_CLIENT);
  ssl_set_authmode(&BACKEND->ssl, SSL_VERIFY_OPTIONAL);

  ssl_set_rng(&BACKEND->ssl, ctr_drbg_random,
              &BACKEND->ctr_drbg);
  ssl_set_bio(&BACKEND->ssl,
              net_recv, &conn->sock[sockindex],
              net_send, &conn->sock[sockindex]);

  ssl_set_ciphersuites(&BACKEND->ssl, ssl_list_ciphersuites());

  /* Check if there's a cached ID we can/should use here! */
  if(SSL_SET_OPTION(primary.sessionid)) {
    void *old_session = NULL;

    Curl_ssl_sessionid_lock(conn);
    if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
      ret = ssl_set_session(&BACKEND->ssl, old_session);
      if(ret) {
        Curl_ssl_sessionid_unlock(conn);
        failf(data, "ssl_set_session returned -0x%x", -ret);
        return CURLE_SSL_CONNECT_ERROR;
      }
      infof(data, "PolarSSL re-using session\n");
    }
    Curl_ssl_sessionid_unlock(conn);
  }

  ssl_set_ca_chain(&BACKEND->ssl,
                   &BACKEND->cacert,
                   &BACKEND->crl,
                   hostname);

  ssl_set_own_cert_rsa(&BACKEND->ssl,
                       &BACKEND->clicert, &BACKEND->rsa);

  if(ssl_set_hostname(&BACKEND->ssl, hostname)) {
    /* ssl_set_hostname() sets the name to use in CN/SAN checks *and* the name
       to set in the SNI extension. So even if curl connects to a host
       specified as an IP address, this function must be used. */
    failf(data, "couldn't set hostname in PolarSSL");
    return CURLE_SSL_CONNECT_ERROR;
  }

#ifdef HAS_ALPN
  if(conn->bits.tls_enable_alpn) {
    static const char *protocols[3];
    int cur = 0;

#ifdef USE_NGHTTP2
    if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
      protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
    }
#endif

    protocols[cur++] = ALPN_HTTP_1_1;
    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);

    protocols[cur] = NULL;

    ssl_set_alpn_protocols(&BACKEND->ssl, protocols);
  }
#endif

#ifdef POLARSSL_DEBUG
  ssl_set_dbg(&BACKEND->ssl, polarssl_debug, data);
#endif

  connssl->connecting_state = ssl_connect_2;

  return CURLE_OK;
}
IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress)
{
	SIOCtlVBuffer CommandBuffer(_CommandAddress);

	u32 _BufferIn = 0, _BufferIn2 = 0, _BufferIn3 = 0;
	u32 BufferInSize = 0, BufferInSize2 = 0, BufferInSize3 = 0;

	u32 BufferOut = 0, BufferOut2 = 0, BufferOut3 = 0;
	u32 BufferOutSize = 0, BufferOutSize2 = 0, BufferOutSize3 = 0;

	if (CommandBuffer.InBuffer.size() > 0)
	{
		_BufferIn = CommandBuffer.InBuffer.at(0).m_Address;
		BufferInSize = CommandBuffer.InBuffer.at(0).m_Size;
	}
	if (CommandBuffer.InBuffer.size() > 1)
	{
		_BufferIn2 = CommandBuffer.InBuffer.at(1).m_Address;
		BufferInSize2 = CommandBuffer.InBuffer.at(1).m_Size;
	}
	if (CommandBuffer.InBuffer.size() > 2)
	{
		_BufferIn3 = CommandBuffer.InBuffer.at(2).m_Address;
		BufferInSize3 = CommandBuffer.InBuffer.at(2).m_Size;
	}

	if (CommandBuffer.PayloadBuffer.size() > 0)
	{
		BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address;
		BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size;
	}
	if (CommandBuffer.PayloadBuffer.size() > 1)
	{
		BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address;
		BufferOutSize2 = CommandBuffer.PayloadBuffer.at(1).m_Size;
	}
	if (CommandBuffer.PayloadBuffer.size() > 2)
	{
		BufferOut3 = CommandBuffer.PayloadBuffer.at(2).m_Address;
		BufferOutSize3 = CommandBuffer.PayloadBuffer.at(2).m_Size;
	}

	// I don't trust SSL to be deterministic, and this is never going to sync
	// as such (as opposed to forwarding IPC results or whatever), so -
	if (Core::g_want_determinism)
	{
		Memory::Write_U32(-1, _CommandAddress + 0x4);
		return IPC_DEFAULT_REPLY;
	}

	switch (CommandBuffer.Parameter)
	{
	case IOCTLV_NET_SSL_NEW:
	{
		int verifyOption = Memory::Read_U32(BufferOut);
		std::string hostname = Memory::GetString(BufferOut2, BufferOutSize2);

		int freeSSL = GetSSLFreeID();
		if (freeSSL)
		{
			int sslID = freeSSL - 1;
			WII_SSL* ssl = &_SSL[sslID];
			int ret = ssl_init(&ssl->ctx);
			if (ret)
			{
				goto _SSL_NEW_ERROR;
			}

			entropy_init(&ssl->entropy);
			const char* pers = "dolphin-emu";
			ret = ctr_drbg_init(&ssl->ctr_drbg, entropy_func,
			                    &ssl->entropy,
			                    (const unsigned char*)pers,
			                    strlen(pers));
			if (ret)
			{
				ssl_free(&ssl->ctx);
				entropy_free(&ssl->entropy);
				goto _SSL_NEW_ERROR;
			}

			ssl_set_rng(&ssl->ctx, ctr_drbg_random, &ssl->ctr_drbg);

			// For some reason we can't use TLSv1.2, v1.1 and below are fine!
			ssl_set_max_version(&ssl->ctx, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_2);

			ssl_set_session(&ssl->ctx, &ssl->session);

			ssl_set_endpoint(&ssl->ctx, SSL_IS_CLIENT);
			ssl_set_authmode(&ssl->ctx, SSL_VERIFY_NONE);
			ssl_set_renegotiation(&ssl->ctx, SSL_RENEGOTIATION_ENABLED);

			ssl->hostname = hostname;
			ssl_set_hostname(&ssl->ctx, ssl->hostname.c_str());

			ssl->active = true;
			Memory::Write_U32(freeSSL, _BufferIn);
		}
		else
		{
_SSL_NEW_ERROR:
			Memory::Write_U32(SSL_ERR_FAILED, _BufferIn);
		}

		INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_NEW (%d, %s) "
			"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
			"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
			"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
			verifyOption, hostname.c_str(),
			_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
			_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
			BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
		break;
	}
	case IOCTLV_NET_SSL_SHUTDOWN:
	{
		int sslID = Memory::Read_U32(BufferOut) - 1;
		if (SSLID_VALID(sslID))
		{
			WII_SSL* ssl = &_SSL[sslID];
			ssl_close_notify(&ssl->ctx);
			ssl_session_free(&ssl->session);
			ssl_free(&ssl->ctx);

			entropy_free(&ssl->entropy);

			x509_crt_free(&ssl->cacert);
			x509_crt_free(&ssl->clicert);

			ssl->hostname.clear();

			ssl->active = false;

			Memory::Write_U32(SSL_OK, _BufferIn);
		}
		else
		{
			Memory::Write_U32(SSL_ERR_ID, _BufferIn);
		}
		INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SHUTDOWN "
			"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
			"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
			"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
			_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
			_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
			BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
		break;
	}
	case IOCTLV_NET_SSL_SETROOTCA:
	{
		INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCA "
			"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
			"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
			"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
			_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
			_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
			BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);


		int sslID = Memory::Read_U32(BufferOut) - 1;
		if (SSLID_VALID(sslID))
		{
			WII_SSL* ssl = &_SSL[sslID];
			int ret = x509_crt_parse_der(
				&ssl->cacert,
				Memory::GetPointer(BufferOut2),
				BufferOutSize2);

			if (ret)
			{
				Memory::Write_U32(SSL_ERR_FAILED, _BufferIn);
			}
			else
			{
				ssl_set_ca_chain(&ssl->ctx, &ssl->cacert, nullptr, ssl->hostname.c_str());
				Memory::Write_U32(SSL_OK, _BufferIn);
			}

			INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCA = %d", ret);
		}
		else
		{
			Memory::Write_U32(SSL_ERR_ID, _BufferIn);
		}
		break;
	}
	case IOCTLV_NET_SSL_SETBUILTINCLIENTCERT:
	{
		INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT "
			"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
			"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
			"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
			_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
			_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
			BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);

		int sslID = Memory::Read_U32(BufferOut) - 1;
		if (SSLID_VALID(sslID))
		{
			WII_SSL* ssl = &_SSL[sslID];
			std::string cert_base_path = File::GetUserPath(D_SESSION_WIIROOT_IDX);
			int ret = x509_crt_parse_file(&ssl->clicert, (cert_base_path + "clientca.pem").c_str());
			int pk_ret = pk_parse_keyfile(&ssl->pk, (cert_base_path + "clientcakey.pem").c_str(), nullptr);
			if (ret || pk_ret)
			{
				x509_crt_free(&ssl->clicert);
				pk_free(&ssl->pk);
				Memory::Write_U32(SSL_ERR_FAILED, _BufferIn);
			}
			else
			{
				ssl_set_own_cert(&ssl->ctx, &ssl->clicert, &ssl->pk);
				Memory::Write_U32(SSL_OK, _BufferIn);
			}

			INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT = (%d, %d)", ret, pk_ret);
		}
		else
		{
			Memory::Write_U32(SSL_ERR_ID, _BufferIn);
			INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT invalid sslID = %d", sslID);
		}
		break;
	}
	case IOCTLV_NET_SSL_REMOVECLIENTCERT:
	{
		INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_REMOVECLIENTCERT "
			"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
			"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
			"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
			_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
			_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
			BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);

		int sslID = Memory::Read_U32(BufferOut) - 1;
		if (SSLID_VALID(sslID))
		{
			WII_SSL* ssl = &_SSL[sslID];
			x509_crt_free(&ssl->clicert);
			pk_free(&ssl->pk);

			ssl_set_own_cert(&ssl->ctx, nullptr, nullptr);
			Memory::Write_U32(SSL_OK, _BufferIn);
		}
		else
		{
			Memory::Write_U32(SSL_ERR_ID, _BufferIn);
			INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT invalid sslID = %d", sslID);
		}
		break;
	}
	case IOCTLV_NET_SSL_SETBUILTINROOTCA:
	{
		int sslID = Memory::Read_U32(BufferOut) - 1;
		if (SSLID_VALID(sslID))
		{
			WII_SSL* ssl = &_SSL[sslID];

			int ret = x509_crt_parse_file(&ssl->cacert, (File::GetUserPath(D_SESSION_WIIROOT_IDX) + "/rootca.pem").c_str());
			if (ret)
			{
				x509_crt_free(&ssl->clicert);
				Memory::Write_U32(SSL_ERR_FAILED, _BufferIn);
			}
			else
			{
				ssl_set_ca_chain(&ssl->ctx, &ssl->cacert, nullptr, ssl->hostname.c_str());
				Memory::Write_U32(SSL_OK, _BufferIn);
			}
			INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA = %d", ret);
		}
		else
		{
			Memory::Write_U32(SSL_ERR_ID, _BufferIn);
		}
		INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA "
			"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
			"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
			"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
			_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
			_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
			BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
		break;
	}
	case IOCTLV_NET_SSL_CONNECT:
	{
		int sslID = Memory::Read_U32(BufferOut) - 1;
		if (SSLID_VALID(sslID))
		{
			WII_SSL* ssl = &_SSL[sslID];
			ssl->sockfd = Memory::Read_U32(BufferOut2);
			INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_CONNECT socket = %d", ssl->sockfd);
			ssl_set_bio(&ssl->ctx, net_recv, &ssl->sockfd, net_send, &ssl->sockfd);
			Memory::Write_U32(SSL_OK, _BufferIn);
		}
		else
		{
			Memory::Write_U32(SSL_ERR_ID, _BufferIn);
		}
		INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_CONNECT "
			"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
			"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
			"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
			_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
			_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
			BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
		break;
	}
	case IOCTLV_NET_SSL_DOHANDSHAKE:
	{
		int sslID = Memory::Read_U32(BufferOut) - 1;
		if (SSLID_VALID(sslID))
		{
			WiiSockMan &sm = WiiSockMan::GetInstance();
			sm.DoSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_DOHANDSHAKE);
			return IPC_NO_REPLY;
		}
		else
		{
			Memory::Write_U32(SSL_ERR_ID, _BufferIn);
		}
		break;
	}
	case IOCTLV_NET_SSL_WRITE:
	{
		int sslID = Memory::Read_U32(BufferOut) - 1;
		if (SSLID_VALID(sslID))
		{
			WiiSockMan &sm = WiiSockMan::GetInstance();
			sm.DoSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_WRITE);
			return IPC_NO_REPLY;
		}
		else
		{
			Memory::Write_U32(SSL_ERR_ID, _BufferIn);
		}
		INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_WRITE "
			"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
			"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
			"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
			_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
			_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
			BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
		INFO_LOG(WII_IPC_SSL, "%s", Memory::GetString(BufferOut2).c_str());
		break;
	}
	case IOCTLV_NET_SSL_READ:
	{

		int ret = 0;
		int sslID = Memory::Read_U32(BufferOut) - 1;
		if (SSLID_VALID(sslID))
		{
			WiiSockMan &sm = WiiSockMan::GetInstance();
			sm.DoSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_READ);
			return IPC_NO_REPLY;
		}
		else
		{
			Memory::Write_U32(SSL_ERR_ID, _BufferIn);
		}

		INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_READ(%d)"
			"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
			"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
			"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
			ret,
			_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
			_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
			BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
		break;
	}
	case IOCTLV_NET_SSL_SETROOTCADEFAULT:
	{
		int sslID = Memory::Read_U32(BufferOut) - 1;
		if (SSLID_VALID(sslID))
		{
			Memory::Write_U32(SSL_OK, _BufferIn);
		}
		else
		{
			Memory::Write_U32(SSL_ERR_ID, _BufferIn);
		}
		INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCADEFAULT "
			"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
			"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
			"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
			_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
			_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
			BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
		break;
	}
	case IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT:
	{
		INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT "
			"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
			"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
			"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
			_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
			_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
			BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);

		int sslID = Memory::Read_U32(BufferOut) - 1;
		if (SSLID_VALID(sslID))
		{
			Memory::Write_U32(SSL_OK, _BufferIn);
		}
		else
		{
			Memory::Write_U32(SSL_ERR_ID, _BufferIn);
		}
		break;
	}
	default:
		ERROR_LOG(WII_IPC_SSL, "%i "
			"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
			"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
			"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
			CommandBuffer.Parameter,
			_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
			_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
			BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
		break;
	}

	// SSL return codes are written to BufferIn
	Memory::Write_U32(0, _CommandAddress+4);

	return IPC_DEFAULT_REPLY;
}