/**
 * Reads and parses the ASN.1 BootSignature block from the given offset
 * @param fd File descriptor to the boot image
 * @param offset Offset from the beginning of file to the signature
 * @param bs Pointer to receive the BootImage structure
 */
static int read_signature(int fd, off64_t offset, BootSignature **bs)
{
    BIO *in = NULL;

    if (!bs) {
        return -1;
    }

    if (lseek64(fd, offset, SEEK_SET) == -1) {
        return -1;
    }

    if ((in = BIO_new_fd(fd, BIO_NOCLOSE)) == NULL) {
        ERR_print_errors(g_error);
        return -1;
    }

    if ((*bs = ASN1_item_d2i_bio(ASN1_ITEM_rptr(BootSignature), in, bs)) == NULL) {
        ERR_print_errors(g_error);
        BIO_free(in);
        return -1;
    }

    BIO_free(in);
    return 0;
}
Esempio n. 2
0
static void hb_PEM_read_bio( PEM_READ_BIO * func )
{
   BIO * bio;

   if( hb_BIO_is( 1 ) )
      bio = hb_BIO_par( 1 );
   else if( HB_ISCHAR( 1 ) )
      bio = BIO_new_file( hb_parc( 1 ), "r" );
   else if( HB_ISNUM( 1 ) )
      bio = BIO_new_fd( hb_parni( 1 ), BIO_NOCLOSE );
   else
      bio = NULL;

   if( bio )
   {
      PHB_ITEM pPassCallback = hb_param( 2, HB_IT_EVALITEM );

      if( pPassCallback )
      {
         hb_retptr( ( *func )( bio, NULL, hb_ssl_pem_password_cb, pPassCallback ) );
      }
      else
      {
         /* NOTE: Dropping 'const' qualifier. [vszakats] */
         hb_retptr( ( *func )( bio, NULL, NULL, ( void * ) hb_parc( 2 ) ) );
      }

      if( ! hb_BIO_is( 1 ) )
         BIO_free( bio );
   }
   else
      hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
Esempio n. 3
0
static void
fatal(const char *msg)
{
	warnx("%s", msg);
	ERR_print_errors(BIO_new_fd(STDERR_FILENO, 0));
	exit(1);
}
Esempio n. 4
0
/**
   \ingroup Core_Crypto
   \brief RSA-encrypts data
   \param out Where to write the encrypted data
   \param in Plaintext
   \param length Size of plaintext
   \param rsa RSA Public Key
*/
int ops_rsa_public_encrypt(unsigned char *out,const unsigned char *in,
			   size_t length,const ops_rsa_public_key_t *rsa)
    {
    RSA *orsa;
    int n;

    //    printf("ops_rsa_public_encrypt: length=%ld\n", length);

    orsa=RSA_new();
    orsa->n=rsa->n;
    orsa->e=rsa->e;

    //    printf("len: %ld\n", length);
    //    ops_print_bn("n: ", orsa->n);
    //    ops_print_bn("e: ", orsa->e);
    n=RSA_public_encrypt(length,in,out,orsa,RSA_NO_PADDING);

    if (n==-1)
        {
        BIO *fd_out;
        fd_out=BIO_new_fd(fileno(stderr), BIO_NOCLOSE);
        ERR_print_errors(fd_out);
        }

    orsa->n=orsa->e=NULL;
    RSA_free(orsa);

    return n;
    }
Esempio n. 5
0
/**
   \ingroup Core_Crypto
   \brief RSA-encrypts data
   \param out Where to write the encrypted data
   \param in Plaintext
   \param length Size of plaintext
   \param pubkey RSA Public Key
*/
int 
__ops_rsa_public_encrypt(uint8_t *out,
			const uint8_t *in,
			size_t length,
			const __ops_rsa_pubkey_t *pubkey)
{
	RSA            *orsa;
	int             n;

	/* printf("__ops_rsa_public_encrypt: length=%ld\n", length); */

	orsa = RSA_new();
	orsa->n = pubkey->n;
	orsa->e = pubkey->e;

	/* printf("len: %ld\n", length); */
	/* __ops_print_bn("n: ", orsa->n); */
	/* __ops_print_bn("e: ", orsa->e); */
	n = RSA_public_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);

	if (n == -1) {
		BIO            *fd_out;

		fd_out = BIO_new_fd(fileno(stderr), BIO_NOCLOSE);
		ERR_print_errors(fd_out);
	}
	orsa->n = orsa->e = NULL;
	RSA_free(orsa);

	return n;
}
void GolgiNetLinux::ssl_connect(void)
{
    DBG.println("Calling ssl_connect");
    bio = BIO_new_fd(sockfd,BIO_NOCLOSE);
    ssl = SSL_new(ctx);
    SSL_set_bio(ssl,bio,bio);
    ssl_connect_continue();
}
Esempio n. 7
0
static LUA_FUNCTION(openssl_bio_new_fd)
{
  int fd = luaL_checkint(L, 1);
  int closeflag = luaL_checkoption(L, 2, "noclose", close_flags);
  BIO *bio = BIO_new_fd(fd, closeflag);

  PUSH_OBJECT(bio, "openssl.bio");
  return 1;
}
Esempio n. 8
0
File: pem.c Progetto: diegopego/core
static void hb_PEM_read_bio( PEM_READ_BIO * func, HB_PEM_TYPES type )
{
   BIO * bio;

   if( hb_BIO_is( 1 ) )
      bio = hb_BIO_par( 1 );
   else if( HB_ISCHAR( 1 ) )
      bio = BIO_new_file( hb_parc( 1 ), "r" );
   else if( HB_ISNUM( 1 ) )
      bio = BIO_new_fd( hb_parni( 1 ), BIO_NOCLOSE );
   else
      bio = NULL;

   if( bio )
   {
      PHB_ITEM pPassCallback = hb_param( 2, HB_IT_EVALITEM );
      pem_password_cb * cb;
      void * cargo, * result;

      if( pPassCallback )
      {
         cb = hb_ssl_pem_password_cb;
         cargo = pPassCallback;
      }
      else
      {
         cb = NULL;
         cargo = ( void * ) hb_parc( 2 ); /* NOTE: Dropping 'const' qualifier. [vszakats] */
      }

      result = ( *func )( bio, NULL, cb, cargo );

      if( result )
      {
         switch( type )
         {
            case hb_PEM_X509:
               hb_X509_ret( ( X509 * ) result, HB_TRUE );
               break;
            case hb_PEM_EVP_PKEY:
               hb_EVP_PKEY_ret( ( EVP_PKEY * ) result );
               break;
            case hb_PEM_ANY:
               hb_retptr( NULL );
               break;
         }
      }
      else
         hb_retptr( NULL );

      if( ! hb_BIO_is( 1 ) )
         BIO_free( bio );
   }
   else
      hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
Esempio n. 9
0
static OCSP_RESPONSE *ocsp_get_response(CLI *c, OCSP_REQUEST *req) {
    BIO *bio=NULL;
    OCSP_REQ_CTX *req_ctx=NULL;
    OCSP_RESPONSE *resp=NULL;
    int err;

    /* connect specified OCSP server (responder) */
    c->fd=s_socket(c->opt->ocsp_addr.sa.sa_family, SOCK_STREAM, 0,
        1, "OCSP: socket (auth_user)");
    if(c->fd<0)
        goto cleanup;
    if(connect_blocking(c, &c->opt->ocsp_addr, addr_len(&c->opt->ocsp_addr)))
        goto cleanup;
    bio=BIO_new_fd(c->fd, BIO_NOCLOSE);
    if(!bio)
        goto cleanup;
    s_log(LOG_DEBUG, "OCSP: server connected");

    /* OCSP protocol communication loop */
    req_ctx=OCSP_sendreq_new(bio, c->opt->ocsp_path, req, -1);
    if(!req_ctx) {
        sslerror("OCSP: OCSP_sendreq_new");
        goto cleanup;
    }
    while(OCSP_sendreq_nbio(&resp, req_ctx)==-1) {
        s_poll_init(c->fds);
        s_poll_add(c->fds, c->fd, BIO_should_read(bio), BIO_should_write(bio));
        err=s_poll_wait(c->fds, c->opt->timeout_busy, 0);
        if(err==-1)
            sockerror("OCSP: s_poll_wait");
        if(err==0)
            s_log(LOG_INFO, "OCSP: s_poll_wait: TIMEOUTbusy exceeded");
        if(err<=0)
            goto cleanup;
    }
    /* s_log(LOG_DEBUG, "OCSP: context state: 0x%x", *(int *)req_ctx); */
    /* http://www.mail-archive.com/[email protected]/msg61691.html */
    if(!resp) {
        if(ERR_peek_error())
            sslerror("OCSP: OCSP_sendreq_nbio");
        else /* OpenSSL error: OCSP_sendreq_nbio does not use OCSPerr */
            s_log(LOG_ERR, "OCSP: OCSP_sendreq_nbio: OpenSSL internal error");
    }

cleanup:
    if(req_ctx)
        OCSP_REQ_CTX_free(req_ctx);
    if(bio)
        BIO_free_all(bio);
    if(c->fd>=0) {
        closesocket(c->fd);
        c->fd=-1; /* avoid double close on cleanup */
    }
    return resp;
}
Esempio n. 10
0
static void hb_PEM_read_bio( PEM_READ_BIO * func, HB_BOOL fX509 )
{
   BIO * bio = NULL;
   HB_BYTE * pBuffer = NULL;
   HB_SIZE nSize = 0;

   if( hb_BIO_is( 1 ) )
      bio = hb_BIO_par( 1 );
   else if( HB_ISCHAR( 1 ) )
   {
      pBuffer = hb_fileLoad( hb_parc( 1 ), 0, &nSize );
      if( pBuffer )
         bio = BIO_new_mem_buf( ( char * ) pBuffer, ( int ) nSize );
   }
   else if( HB_ISNUM( 1 ) )
      bio = BIO_new_fd( hb_parni( 1 ), BIO_NOCLOSE );

   if( bio )
   {
      PHB_ITEM pPassCallback = hb_param( 2, HB_IT_EVALITEM );
      pem_password_cb * cb;
      void * cargo, * result;

      if( pPassCallback )
      {
         cb = hb_ssl_pem_password_cb;
         cargo = pPassCallback;
      }
      else
      {
         cb = NULL;
         cargo = HB_UNCONST( hb_parc( 2 ) );  /* NOTE: Discarding 'const' qualifier, OpenSSL will memcpy() it */
      }

      result = ( *func )( bio, NULL, cb, cargo );

      if( fX509 && result )
         hb_X509_ret( ( X509 * ) result, HB_TRUE );
      else
         hb_retptr( result );

      if( ! hb_BIO_is( 1 ) )
         BIO_free( bio );

      if( pBuffer )
      {
         OPENSSL_cleanse( pBuffer, ( size_t ) nSize );
         hb_xfree( pBuffer );
      }
   }
   else
      hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
Esempio n. 11
0
int main (int argc, char *argv[])
{
  BIO *ich = BIO_new_fd(0, 1);
  BIO *och = BIO_new_fd(1, 1);
  BIO *fch = BIO_new(BIO_f_linebreak());
  char buffer[4098];
  int n;

  if (ich == NULL || och == NULL || fch == NULL)
    return 1;

  BIO_push(fch, ich);
  ich = fch;
  fch = NULL;

  while ((n = BIO_read(ich, buffer, sizeof(buffer))) > 0)
    BIO_write(och, buffer, n);

  BIO_free_all(ich);
  BIO_free_all(och);
  return 0;
}
Esempio n. 12
0
static void
save_dh_params(DH *p, const char *filename) {
  int fd;
  BIO *bio;
  if(p == NULL || filename == NULL) return;
  fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, 0600);
  if(fd < 0) return;
  bio = BIO_new_fd(fd, 0);
  if(bio == NULL) { close(fd); return; }
  mtevL(mtev_notice, "Saving DH parameters to %s.\n", filename);
  PEM_write_bio_DHparams(bio,p);
  BIO_free(bio);
  fchmod(fd, 0400);
  close(fd);
  return;
}
int main(int argc, char *argv[])
{
    if (argc != 2) {
        usage();
        return 1;
    }

    /* BIO descriptor for logging OpenSSL errors to stderr */
    if ((g_error = BIO_new_fd(STDERR_FILENO, BIO_NOCLOSE)) == NULL) {
        printf("Failed to allocate a BIO handle for error output\n");
        return 1;
    }

    ERR_load_crypto_strings();

    return verify(argv[1]);
}
Esempio n. 14
0
bool write_pem(char *path, uint8_t *passwd, size_t len, EVP_PKEY *key, EC_GROUP *group, size_t certs, ...) {
    const EVP_CIPHER *cipher = passwd ? EVP_aes_256_cbc() : NULL;
    va_list ap;
    BIO *out = NULL;

    int fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0600);
    if (fd >= 0 && (out = BIO_new_fd(fd, BIO_CLOSE))) {
        PEM_write_bio_ECPKParameters(out, group);
        PEM_write_bio_PKCS8PrivateKey(out, key, cipher, (char *) passwd, len, NULL, NULL);

        va_start(ap, certs);
        for (size_t i = 0; i < certs; i++) {
            X509 *cert = va_arg(ap, X509 *);
            PEM_write_bio_X509(out, cert);
        }
        va_end(ap);

        BIO_free(out);
    }
e_TlsError TlsInitHandshake(t_TlsConnection *p_TlsConnection)
{
    DEBUG_LOG_PRINT_LEV2(("TlsInitHandshake : handle %d : Entry\n" , p_TlsConnection->handle ));

    p_TlsConnection->p_BIO =
 //        BIO_new_socket(
         BIO_new_fd(
         p_TlsConnection->socket,
            BIO_NOCLOSE);

      if(p_TlsConnection->p_BIO == NULL)
      {
         DEBUG_LOG_PRINT_LEV2(("ERROR failed to create SSL BIO on socket\n" ));
         if(p_TlsConnection->socket)   close(p_TlsConnection->socket);
         return K_TLS_ERROR_BIO_INIT;
      }

    // Prepare for SSL layer
     p_TlsConnection->p_SSL = SSL_new(gp_SSL_CTX);
     if(p_TlsConnection->p_SSL == NULL)
     {
        DEBUG_LOG_PRINT_LEV2(("ERROR failed to create SSL structure for SSL connection\n" ));
        BIO_free(p_TlsConnection->p_BIO);
        p_TlsConnection->p_BIO = NULL;
        return K_TLS_ERROR_SSL_INIT;
     }

     SSL_set_bio(
        p_TlsConnection->p_SSL,
        p_TlsConnection->p_BIO,
        p_TlsConnection->p_BIO);
     SSL_set_mode(p_TlsConnection->p_SSL, SSL_MODE_AUTO_RETRY);

     TlsTransitionState(p_TlsConnection , K_TLS_STATE_HANDSHAKE_IN_PROGRESS);

     DEBUG_LOG_PRINT_LEV2(("TlsInitHandshake : Exit\n"));

     return TlsDoHandshake( p_TlsConnection );
}
Esempio n. 16
0
static void hb_PEM_read_bio( PEM_READ_BIO * func )
{
   BIO * bio = NULL;
   HB_BYTE * pBuffer = NULL;
   HB_SIZE nSize = 0;

   if( hb_BIO_is( 1 ) )
      bio = hb_BIO_par( 1 );
   else if( HB_ISCHAR( 1 ) )
   {
      pBuffer = hb_fileLoad( hb_parc( 1 ), 0, &nSize );
      if( pBuffer )
         bio = BIO_new_mem_buf( ( char * ) pBuffer, ( int ) nSize );
   }
   else if( HB_ISNUM( 1 ) )
      bio = BIO_new_fd( hb_parni( 1 ), BIO_NOCLOSE );

   if( bio )
   {
      PHB_ITEM pPassCallback = hb_param( 2, HB_IT_EVALITEM );

      if( pPassCallback )
         hb_retptr( ( *func )( bio, NULL, hb_ssl_pem_password_cb, pPassCallback ) );
      else
         hb_retptr( ( *func )( bio, NULL, NULL, ( void * ) hb_parc( 2 ) ) );  /* NOTE: Dropping 'const' qualifier. [vszakats] */

      if( ! hb_BIO_is( 1 ) )
         BIO_free( bio );

      if( pBuffer )
      {
         OPENSSL_cleanse( pBuffer, ( size_t ) nSize );
         hb_xfree( pBuffer );
      }
   }
   else
      hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
Esempio n. 17
0
NOEXPORT OCSP_RESPONSE *ocsp_get_response(CLI *c,
        OCSP_REQUEST *req, char *url) {
    BIO *bio=NULL;
    OCSP_REQ_CTX *req_ctx=NULL;
    OCSP_RESPONSE *resp=NULL;
    int err;
    char *host=NULL, *port=NULL, *path=NULL;
    SOCKADDR_UNION addr;
    int ssl;

    /* parse the OCSP URL */
    if(!OCSP_parse_url(url, &host, &port, &path, &ssl)) {
        s_log(LOG_ERR, "OCSP: Failed to parse the OCSP URL");
        goto cleanup;
    }
    if(ssl) {
        s_log(LOG_ERR, "OCSP: SSL not supported for OCSP"
            " - additional stunnel service needs to be defined");
        goto cleanup;
    }
    memset(&addr, 0, sizeof addr);
    addr.in.sin_family=AF_INET;
    if(!hostport2addr(&addr, host, port)) {
        s_log(LOG_ERR, "OCSP: Failed to resolve the OCSP server address");
        goto cleanup;
    }

    /* connect specified OCSP server (responder) */
    c->fd=s_socket(addr.sa.sa_family, SOCK_STREAM, 0, 1, "OCSP: socket");
    if(c->fd<0)
        goto cleanup;
    if(s_connect(c, &addr, addr_len(&addr)))
        goto cleanup;
    bio=BIO_new_fd(c->fd, BIO_NOCLOSE);
    if(!bio)
        goto cleanup;
    s_log(LOG_DEBUG, "OCSP: response retrieved");

    /* OCSP protocol communication loop */
    req_ctx=OCSP_sendreq_new(bio, path, req, -1);
    if(!req_ctx) {
        sslerror("OCSP: OCSP_sendreq_new");
        goto cleanup;
    }
    while(OCSP_sendreq_nbio(&resp, req_ctx)==-1) {
        s_poll_init(c->fds);
        s_poll_add(c->fds, c->fd, BIO_should_read(bio), BIO_should_write(bio));
        err=s_poll_wait(c->fds, c->opt->timeout_busy, 0);
        if(err==-1)
            sockerror("OCSP: s_poll_wait");
        if(err==0)
            s_log(LOG_INFO, "OCSP: s_poll_wait: TIMEOUTbusy exceeded");
        if(err<=0)
            goto cleanup;
    }
#if 0
    s_log(LOG_DEBUG, "OCSP: context state: 0x%x", *(int *)req_ctx);
#endif
    /* http://www.mail-archive.com/[email protected]/msg61691.html */
    if(resp) {
        s_log(LOG_DEBUG, "OCSP: request completed");
    } else {
        if(ERR_peek_error())
            sslerror("OCSP: OCSP_sendreq_nbio");
        else /* OpenSSL error: OCSP_sendreq_nbio does not use OCSPerr */
            s_log(LOG_ERR, "OCSP: OCSP_sendreq_nbio: OpenSSL internal error");
    }

cleanup:
    if(req_ctx)
        OCSP_REQ_CTX_free(req_ctx);
    if(bio)
        BIO_free_all(bio);
    if(c->fd>=0) {
        closesocket(c->fd);
        c->fd=-1; /* avoid double close on cleanup */
    }
    if(host)
        OPENSSL_free(host);
    if(port)
        OPENSSL_free(port);
    if(path)
        OPENSSL_free(path);
    return resp;
}
Esempio n. 18
0
void initBIO(void)
{
    _out = BIO_new_fd(fileno(stdout), BIO_NOCLOSE);
}
Esempio n. 19
0
/* ------------------------------------------------------------------------- *
 * scanner_connect creates a new session to the openvas server and returns   *
 * the file descriptor to it.                                                *
 * ------------------------------------------------------------------------- */
int scanner_connect(char * ip, int port) {
  int sockfd;
  struct sockaddr_in dest_addr;
  static SSL_CTX        *ssl_ctx = NULL;
  X509			*servercert;

  if(DEBUG) printf("Creating socket file descriptor.\n");
  sockfd = socket(AF_INET, SOCK_STREAM, 0);

  if(DEBUG) printf("Loading content into filedescriptor.\n");
  dest_addr.sin_family=AF_INET;
  dest_addr.sin_port=htons(port);
  dest_addr.sin_addr.s_addr=inet_addr(ip);

  /* Zeroing the rest of the struct */

  memset(&(dest_addr.sin_zero), '\0', 8);

  if(DEBUG) printf("Try connecting to %s.\n", DEST_IP);

  if ( connect(sockfd, (struct sockaddr *) &dest_addr,
                              sizeof(struct sockaddr)) == -1 ) {
    if(DEBUG) perror("Error connecting");
    return -1;
  } else {
    if(DEBUG) printf("Connected to: %s.\n", DEST_IP);
  }

  ssl = NULL;

  /* initialize SSL library and register algorithms */
  if(SSL_library_init() < 0)
    printf("Could not initialize the OpenSSL library !\n");

  /* load  the SSL error messages */
  SSL_load_error_strings();

  /* create a new SSL_CTX object as framework for TLS/SSL enabled functions */
  /* for TLSv1, we use TLSv1_client_method() */
  if((ssl_ctx = SSL_CTX_new(TLSv1_client_method())) == NULL) 
    printf("SSL_CTX_new() context creation error\n");

  /* enable all SSL engine bug workaround options (i.e. Netscape, Microsoft) */
  if(SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL) < 0)
    printf("SSL_CTX_set_options error\n");

  /* choose list of available SSL_CIPHERs with a control string */
  if(! SSL_CTX_set_cipher_list(ssl_ctx, CIPHER_LIST))
    printf("SSL_CTX_set_cipher_list error\n");

  /* create a new SSL structure for a connection */
  if((ssl = SSL_new(ssl_ctx)) == NULL)
     printf("SSL_new() general error\n");

  /* connect the SSL object with the socket file descriptor */
  if(! SSL_set_fd(ssl, sockfd))
     printf("SSL_set_fd() error connecting to socket.\n");

  /* initiate the TLS/SSL handshake with an TLS/SSL server */
  if(SSL_connect(ssl) <= 0)
     printf("SSL_connect() error during SSL handshake\n");

  /* show the connection cipher that is used */
  if(DEBUG) printf("SSL_get_cipher = %s\n", SSL_get_cipher(ssl));

  /* get the received openvas server certificate */
  if(! (servercert = SSL_get_peer_certificate(ssl)))
    printf("SSL_get_peer_certificate() error: cannot get server certificate\n");

  /* print the received openvas server certificate */
  if(DEBUG == 2) {
    BIO                  *outbio;
    outbio = BIO_new_fd(fileno(stdout), BIO_NOCLOSE);
    if (! (X509_print_ex(outbio, servercert, 0, XN_FLAG_SEP_MULTILINE)))
      BIO_printf(outbio, "Error printing certificate text information\n");
  }

  return 1;
}
Esempio n. 20
0
static int ocsp_check(CLI *c, X509_STORE_CTX *callback_ctx) {
    int error, retval=0;
    SOCKADDR_UNION addr;
    X509 *cert;
    X509 *issuer=NULL;
    OCSP_CERTID *certID;
    BIO *bio=NULL;
    OCSP_REQUEST *request=NULL;
    OCSP_RESPONSE *response=NULL;
    OCSP_BASICRESP *basicResponse=NULL;
    ASN1_GENERALIZEDTIME *revoked_at=NULL,
        *this_update=NULL, *next_update=NULL;
    int status, reason;

    /* connect specified OCSP server (responder) */
    c->fd=s_socket(c->opt->ocsp_addr.addr[0].sa.sa_family, SOCK_STREAM, 0,
        0, "OCSP: socket (auth_user)");
    if(c->fd<0)
        return 0; /* reject connection */
    memcpy(&addr, &c->opt->ocsp_addr.addr[0], sizeof addr);
    if(connect_blocking(c, &addr, addr_len(addr)))
        goto cleanup;
    s_log(LOG_DEBUG, "OCSP: server connected");

    /* get current certificate ID */
    cert=X509_STORE_CTX_get_current_cert(callback_ctx); /* get current cert */
    if(X509_STORE_CTX_get1_issuer(&issuer, callback_ctx, cert)!=1) {
        sslerror("OCSP: X509_STORE_CTX_get1_issuer");
        goto cleanup;
    }
    certID=OCSP_cert_to_id(0, cert, issuer);
    if(!certID) {
        sslerror("OCSP: OCSP_cert_to_id");
        goto cleanup;
    }

    /* build request */
    request=OCSP_REQUEST_new();
    if(!request) {
        sslerror("OCSP: OCSP_REQUEST_new");
        goto cleanup;
    }
    if(!OCSP_request_add0_id(request, certID)) {
        sslerror("OCSP: OCSP_request_add0_id");
        goto cleanup;
    }
    OCSP_request_add1_nonce(request, 0, -1);

    /* send the request and get a response */
    /* FIXME: this code won't work with ucontext threading */
    /* (blocking sockets are used) */
    bio=BIO_new_fd(c->fd, BIO_NOCLOSE);
    response=OCSP_sendreq_bio(bio, c->opt->ocsp_path, request);
    if(!response) {
        sslerror("OCSP: OCSP_sendreq_bio");
        goto cleanup;
    }
    error=OCSP_response_status(response);
    if(error!=OCSP_RESPONSE_STATUS_SUCCESSFUL) {
        s_log(LOG_WARNING, "OCSP: Responder error: %d: %s",
            error, OCSP_response_status_str(error));
        goto cleanup;
    }
    s_log(LOG_DEBUG, "OCSP: Response received");

    /* verify the response */
    basicResponse=OCSP_response_get1_basic(response);
    if(!basicResponse) {
        sslerror("OCSP: OCSP_response_get1_basic");
        goto cleanup;
    }
    if(OCSP_check_nonce(request, basicResponse)<=0) {
        sslerror("OCSP: OCSP_check_nonce");
        goto cleanup;
    }
    if(OCSP_basic_verify(basicResponse, NULL,
            c->opt->revocation_store, c->opt->ocsp_flags)<=0) {
        sslerror("OCSP: OCSP_basic_verify");
        goto cleanup;
    }
    if(!OCSP_resp_find_status(basicResponse, certID, &status, &reason,
            &revoked_at, &this_update, &next_update)) {
        sslerror("OCSP: OCSP_resp_find_status");
        goto cleanup;
    }
    s_log(LOG_NOTICE, "OCSP: Status: %d: %s",
        status, OCSP_cert_status_str(status));
    log_time(LOG_INFO, "OCSP: This update", this_update);
    log_time(LOG_INFO, "OCSP: Next update", next_update);
    /* check if the response is valid for at least one minute */
    if(!OCSP_check_validity(this_update, next_update, 60, -1)) {
        sslerror("OCSP: OCSP_check_validity");
        goto cleanup;
    }
    if(status==V_OCSP_CERTSTATUS_REVOKED) {
        if(reason==-1)
            s_log(LOG_WARNING, "OCSP: Certificate revoked");
        else
            s_log(LOG_WARNING, "OCSP: Certificate revoked: %d: %s",
                reason, OCSP_crl_reason_str(reason));
        log_time(LOG_NOTICE, "OCSP: Revoked at", revoked_at);
        goto cleanup;
    }
    retval=1; /* accept connection */
cleanup:
    if(bio)
        BIO_free_all(bio);
    if(issuer)
        X509_free(issuer);
    if(request)
        OCSP_REQUEST_free(request);
    if(response)
        OCSP_RESPONSE_free(response);
    if(basicResponse)
        OCSP_BASICRESP_free(basicResponse);
    closesocket(c->fd);
    c->fd=-1; /* avoid double close on cleanup */
    return retval;
}
Esempio n. 21
0
BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout)
{
	int status;
	UINT32 option_value;
	socklen_t option_len;

	if (!hostname)
		return FALSE;

	if (hostname[0] == '/')
	{
		tcp->sockfd = freerdp_uds_connect(hostname);

		if (tcp->sockfd < 0)
			return FALSE;

		tcp->socketBio = BIO_new_fd(tcp->sockfd, 1);

		if (!tcp->socketBio)
			return FALSE;
	}
	else
	{
		fd_set cfds;
		struct timeval tv;

		tcp->socketBio = BIO_new(BIO_s_connect());

		if (!tcp->socketBio)
			return FALSE;

		if (BIO_set_conn_hostname(tcp->socketBio, hostname) < 0 || BIO_set_conn_int_port(tcp->socketBio, &port) < 0)
			return FALSE;

		BIO_set_nbio(tcp->socketBio, 1);

		status = BIO_do_connect(tcp->socketBio);

		if ((status <= 0) && !BIO_should_retry(tcp->socketBio))
			return FALSE;

		tcp->sockfd = BIO_get_fd(tcp->socketBio, NULL);

		if (tcp->sockfd < 0)
			return FALSE;

		if (status <= 0)
		{
			FD_ZERO(&cfds);
			FD_SET(tcp->sockfd, &cfds);

			tv.tv_sec = timeout;
			tv.tv_usec = 0;

			status = select(tcp->sockfd + 1, NULL, &cfds, NULL, &tv);

			if (status == 0)
			{
				return FALSE; /* timeout */
			}
		}

		BIO_set_close(tcp->socketBio, BIO_NOCLOSE);
		BIO_free(tcp->socketBio);

		tcp->socketBio = BIO_new(BIO_s_simple_socket());

		if (!tcp->socketBio)
			return -1;

		BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE);
	}

	SetEventFileDescriptor(tcp->event, tcp->sockfd);

	tcp_get_ip_address(tcp);
	tcp_get_mac_address(tcp);

	option_value = 1;
	option_len = sizeof(option_value);

	if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0)
		fprintf(stderr, "%s: unable to set TCP_NODELAY\n", __FUNCTION__);

	/* receive buffer must be a least 32 K */
	if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0)
	{
		if (option_value < (1024 * 32))
		{
			option_value = 1024 * 32;
			option_len = sizeof(option_value);

			if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len) < 0)
			{
				fprintf(stderr, "%s: unable to set receive buffer len\n", __FUNCTION__);
				return FALSE;
			}
		}
	}

	if (!tcp_set_keep_alive_mode(tcp))
		return FALSE;

	tcp->bufferedBio = BIO_new(BIO_s_buffered_socket());

	if (!tcp->bufferedBio)
		return FALSE;

	tcp->bufferedBio->ptr = tcp;

	tcp->bufferedBio = BIO_push(tcp->bufferedBio, tcp->socketBio);

	return TRUE;
}