github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/support_libraries/tao_support/ssl_helpers.cc (about)

     1  #include <stdio.h>
     2  #include <stdlib.h>
     3  #include <sys/types.h>
     4  #include <sys/stat.h>
     5  #include <fcntl.h>
     6  #include <unistd.h>
     7  #include <string.h>
     8  #include <errno.h>
     9  
    10  #include <netinet/in.h>
    11  #include <sys/socket.h>
    12  #include <arpa/inet.h>
    13  
    14  #include <ssl_helpers.h>
    15  
    16  #include <openssl/rsa.h>
    17  #include <openssl/x509.h>
    18  #include <openssl/ssl.h>
    19  #include <openssl/evp.h>
    20  #include <openssl/asn1.h>
    21  #include <openssl/err.h>
    22  #include <openssl/aes.h>
    23  #include <openssl/hmac.h>
    24  #include <openssl/rand.h>
    25  
    26  #include <string>
    27  #include <thread>
    28  
    29  #include <messages.pb.h>
    30  #include <keys.pb.h>
    31  
    32  using std::string;
    33  using std::unique_ptr;
    34  using std::thread;
    35  using std::vector;
    36  
    37  //
    38  // Copyright 2015 Google Corporation, All Rights Reserved.
    39  //
    40  // Licensed under the Apache License, Version 2.0 (the "License");
    41  // you may not use this file except in compliance with the License.
    42  // You may obtain a copy of the License at
    43  //     http://www.apache.org/licenses/LICENSE-2.0
    44  // or in the the file LICENSE-2.0.txt in the top level sourcedirectory
    45  // Unless required by applicable law or agreed to in writing, software
    46  // distributed under the License is distributed on an "AS IS" BASIS,
    47  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    48  // See the License for the specific language governing permissions and
    49  // limitations under the License
    50  //
    51  // Portions of this code were derived TPM2.0-TSS published
    52  // by Intel under the license set forth in intel_license.txt
    53  // and downloaded on or about August 6, 2015.
    54  // File: helpers.cc
    55  
    56  // standard buffer size
    57  #define MAX_SIZE_PARAMS 4096
    58  
    59  void PrintPrivateRSAKey(RSA& key) {
    60    if (key.n != nullptr) {
    61      printf("\nModulus: \n");
    62      BN_print_fp(stdout, key.n);
    63      printf("\n");
    64    }
    65    if (key.e != nullptr) {
    66      printf("\ne: \n");
    67      BN_print_fp(stdout, key.e);
    68      printf("\n");
    69    }
    70    if (key.d != nullptr) {
    71      printf("\nd: \n");
    72      BN_print_fp(stdout, key.d);
    73      printf("\n");
    74    }
    75    if (key.p != nullptr) {
    76      printf("\np: \n");
    77      BN_print_fp(stdout, key.p);
    78      printf("\n");
    79    }
    80    if (key.q != nullptr) {
    81      printf("\nq: \n");
    82      BN_print_fp(stdout, key.q);
    83      printf("\n");
    84    }
    85  }
    86  
    87  BIGNUM* bin_to_BN(int len, byte* buf) {
    88    BIGNUM* bn = BN_bin2bn(buf, len, nullptr);
    89    return bn;
    90  }
    91  
    92  string* BN_to_bin(BIGNUM& n) {
    93    byte buf[MAX_SIZE_PARAMS];
    94  
    95    int len = BN_bn2bin(&n, buf);
    96    return new string((const char*)buf, len);
    97  }
    98  
    99  bool BN_to_string(BIGNUM& n, string* out) {
   100    byte buf[MAX_SIZE_PARAMS];
   101  
   102    int len = BN_bn2bin(&n, buf);
   103    out->assign((const char*)buf, len);
   104    return true;
   105  }
   106  
   107  bool EC_SIG_serialize(ECDSA_SIG* sig, string* out) {
   108    string* r_out = BN_to_bin(*sig->r);
   109    string* s_out = BN_to_bin(*sig->s);
   110    tao::EcdsaSig serialized_proto;
   111    serialized_proto.set_r_val(*r_out);
   112    serialized_proto.set_s_val(*s_out);
   113    delete r_out;
   114    delete s_out;
   115    if (!serialized_proto.SerializeToString(out)) {
   116      return false;
   117    }
   118    return true;
   119  }
   120  
   121  bool EC_SIG_deserialize(string& in, ECDSA_SIG* sig) {
   122    tao::EcdsaSig serialized_proto;
   123    if (!serialized_proto.ParseFromString(in)) {
   124      return false;
   125    }
   126    BIGNUM* r = bin_to_BN(serialized_proto.r_val().size(), (byte*)serialized_proto.r_val().data());
   127    BIGNUM* s = bin_to_BN(serialized_proto.s_val().size(), (byte*)serialized_proto.s_val().data());
   128    sig->r = r;
   129    sig->s = s;
   130    return true;
   131  }
   132  
   133  class extEntry {
   134  public:
   135    char* key_;
   136    char* value_;
   137  
   138    extEntry(const char* k, const char* v);
   139    extEntry();
   140    char* getKey();
   141    char* getValue();
   142  };
   143  
   144  extEntry::extEntry(const char* k, const char* v) {
   145    key_ = (char*)strdup(k);
   146    value_ = (char*)strdup(v);
   147  }
   148  
   149  extEntry::extEntry() {
   150    key_ = nullptr;
   151    value_ = nullptr;
   152  }
   153  
   154  char* extEntry::getKey() {
   155    return key_;
   156  }
   157  
   158  char* extEntry::getValue() {
   159    return value_;
   160  }
   161  
   162  bool addExtensionsToCert(int num_entry, extEntry** entries, X509* cert) {
   163    // add extensions
   164    X509V3_CTX ctx;
   165    X509V3_set_ctx_nodb(&ctx);
   166    X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
   167    for (int i = 0; i < num_entry; i++) {
   168      if (entries[i]->getValue() == nullptr || strlen(entries[i]->getValue()) ==0)
   169        continue;
   170      int nid = OBJ_txt2nid(entries[i]->getKey());
   171      X509_EXTENSION* ext = X509V3_EXT_conf_nid(NULL, &ctx, nid, entries[i]->getValue());
   172      if (ext == 0) {
   173        printf("Bad ext_conf %d\n", i);
   174        printf("ERR: %s\n", ERR_lib_error_string(ERR_get_error()));
   175        return false;
   176      }
   177      if (!X509_add_ext(cert, ext, -1)) {
   178        printf("Bad add ext %d\n", i);
   179        printf("ERR: %s\n", ERR_lib_error_string(ERR_get_error()));
   180        return false;
   181      }
   182      X509_EXTENSION_free(ext);
   183    }
   184    return true;
   185  }
   186  
   187  bool GenerateX509CertificateRequest(EVP_PKEY* subjectKey, string& common_name,
   188              bool sign_request, X509_REQ* req) {
   189    X509_NAME* subject = X509_NAME_new();
   190    X509_REQ_set_version(req, 2L);
   191    if (subject == nullptr) {
   192      printf("Can't alloc x509 name\n");
   193      return false;
   194    }
   195    if (common_name.size() > 0) {
   196      int nid = OBJ_txt2nid("CN");
   197      X509_NAME_ENTRY* ent = X509_NAME_ENTRY_create_by_NID(nullptr, nid,
   198          MBSTRING_ASC, (byte*)common_name.c_str(), -1);
   199      if (ent == nullptr) {
   200        printf("X509_NAME_ENTRY return is null, nid: %d\n", nid);
   201        return false;
   202      }
   203      if (X509_NAME_add_entry(subject, ent, -1, 0) != 1) {
   204        printf("Can't add name ent\n");
   205        return false;
   206      }
   207    }
   208    // TODO: do the foregoing for the other name components
   209    if (X509_REQ_set_subject_name(req, subject) != 1)  {
   210      printf("Can't set x509 subject\n");
   211      return false;
   212    }
   213  
   214    // fill key parameters in request
   215    if (sign_request) {
   216      const EVP_MD* digest = EVP_sha256();
   217      if (!X509_REQ_sign(req, subjectKey, digest)) {
   218        printf("Sign request fails\n");
   219        printf("ERR: %s\n", ERR_lib_error_string(ERR_get_error()));
   220      }
   221    }
   222    if (X509_REQ_set_pubkey(req, subjectKey) ==0) {
   223        printf("X509_REQ_set_pubkey failed\n");
   224    }
   225    return true;
   226  }
   227  
   228  bool SignX509Certificate(EVP_PKEY* signingKey, bool f_isCa,
   229                           bool f_canSign, string& signing_issuer,
   230                           string& keyUsage, string& extendedKeyUsage,
   231                           int64 duration, EVP_PKEY* signedKey,
   232                           X509_REQ* req, bool verify_req_sig, X509* cert) {
   233    if (signedKey == nullptr)
   234      signedKey = X509_REQ_get_pubkey(req);
   235    if (signedKey == nullptr) {
   236      printf("Can't get pubkey\n");
   237      return false;
   238    }
   239  
   240    if (verify_req_sig) {
   241      if (X509_REQ_verify(req, signedKey) != 1) {
   242        printf("Req does not verify\n");
   243        return false;
   244      }
   245    }
   246    
   247    uint64_t serial = 1;
   248    const EVP_MD* digest = EVP_sha256();
   249    X509_NAME* name;
   250    X509_set_version(cert, 2L);
   251    ASN1_INTEGER_set(X509_get_serialNumber(cert), serial++);
   252  
   253    name = X509_REQ_get_subject_name(req);
   254    if (X509_set_subject_name(cert, name) != 1) {
   255      printf("Can't set subject name\n");
   256      return false;
   257    }
   258    if (X509_set_pubkey(cert, signedKey) != 1) {
   259      printf("Can't set pubkey\n");
   260      return false;
   261    }
   262    if (!X509_gmtime_adj(X509_get_notBefore(cert), 0)) {
   263      printf("Can't adj notBefore\n");
   264      return false;
   265    }
   266    if (!X509_gmtime_adj(X509_get_notAfter(cert), duration)) {
   267      printf("Can't adj notAfter\n");
   268      return false;
   269    }
   270    X509_NAME* issuer = X509_NAME_new();
   271    int nid = OBJ_txt2nid("CN");
   272    X509_NAME_ENTRY* ent = X509_NAME_ENTRY_create_by_NID(nullptr, nid,
   273        MBSTRING_ASC, (byte*)signing_issuer.c_str(), -1);
   274    if (X509_NAME_add_entry(issuer, ent, -1, 0) != 1) {
   275      printf("Can't add issuer name ent: %s, %ld\n",
   276             signing_issuer.c_str(), (long unsigned)ent);
   277      printf("ERR: %s\n", ERR_lib_error_string(ERR_get_error()));
   278      return false;
   279    }
   280    if (X509_set_issuer_name(cert, issuer) != 1) {
   281      printf("Can't set issuer name\n");
   282      return false;
   283    }
   284  
   285    // Add extensions which should be
   286    //    X509v3 extensions:
   287    //        X509v3 Key Usage: critical
   288    //            Key Agreement, Certificate Sign
   289    //        X509v3 Extended Key Usage: 
   290    //            TLS Web Server Authentication, TLS Web Client Authentication
   291    //        X509v3 Basic Constraints: critical
   292    //            CA:TRUE
   293    extEntry* entries[128];
   294    int n = 0;
   295    if (f_isCa) {
   296      entries[n++] = new extEntry("basicConstraints", "critical,CA:TRUE");
   297    }
   298    entries[n++] = new extEntry("keyUsage", keyUsage.c_str());
   299    entries[n++] = new extEntry("extendedKeyUsage", extendedKeyUsage.c_str());
   300    if (!addExtensionsToCert(n, entries, cert)) {
   301      printf("Can't add extensions\n");
   302      return false;
   303    }
   304  
   305    if (!X509_sign(cert, signingKey, digest)) {
   306      printf("Bad PKEY type\n");
   307      return false;
   308    }
   309    return true;
   310  }
   311  
   312  void XorBlocks(int size, byte* in1, byte* in2, byte* out) {
   313    int i;
   314  
   315    for (i = 0; i < size; i++)
   316      out[i] = in1[i] ^ in2[i];
   317  }
   318  
   319  void bumpCtr(uint64_t* ctr) {
   320    uint64_t x = ctr[0] + 1;
   321    if (x < ctr[0])
   322      ctr[1]++;
   323    ctr[0] = x;
   324  }
   325  
   326  void toLittleEndian(byte* in, uint64_t* ctr) {
   327    byte* out = (byte*) ctr;
   328    for (int i = 0; i < 16; i++)
   329      out[15 - i] = in[i];
   330  }
   331  
   332  void toBigEndian(uint64_t* ctr, byte* out) {
   333    byte* in = (byte*) ctr;
   334    for (int i = 0; i < 16; i++)
   335      out[15 - i] = in[i];
   336  }
   337  
   338  bool AesCtrCrypt(string& iv, int key_size_bits, byte* key, int size,
   339                      byte* in, byte* out) {
   340    AES_KEY ectx;
   341    byte block[32];
   342    uint64_t ctr[2];
   343  
   344    toLittleEndian((byte*)iv.data(), ctr);
   345    AES_set_encrypt_key(key, key_size_bits, &ectx);
   346  
   347    while (size > 0) {
   348      toBigEndian(ctr, block);
   349      AES_encrypt((byte*)ctr, block, &ectx);
   350      XorBlocks(16, block, in, out);
   351      in += 16;
   352      out += 16;
   353      size -= 16;
   354      bumpCtr(ctr);
   355    }
   356    return true;
   357  }
   358  
   359  #define AESBLKSIZE 16
   360  
   361  bool AesCFBEncrypt(byte* key, int in_size, byte* in, int iv_size, byte* iv,
   362                     int* out_size, byte* out) {
   363    byte last_cipher[32];
   364    byte cipher_block[32];
   365    int size = 0;
   366    int current_size;
   367  
   368    AES_KEY ectx;
   369    AES_set_encrypt_key(key, 128, &ectx);
   370  
   371    // Don't write iv, called already knows it
   372    if(iv_size != AESBLKSIZE) return false;
   373    memcpy(last_cipher, iv, AESBLKSIZE);
   374  
   375    while (in_size > 0) {
   376      if ((size + AESBLKSIZE) > *out_size) return false; 
   377      // C[0] = IV, C[i] = P[i] ^ E(K, C[i-1])
   378      AES_encrypt(last_cipher, cipher_block, &ectx);
   379      if (in_size >= AESBLKSIZE)
   380        current_size = AESBLKSIZE;
   381      else
   382        current_size = in_size;
   383      XorBlocks(AESBLKSIZE, cipher_block, in, last_cipher);
   384      memcpy(out, last_cipher, current_size);
   385      out += current_size;
   386      size += current_size;
   387      in += current_size;
   388      in_size -= current_size;
   389    }
   390    *out_size = size;
   391    return true;
   392  }
   393  
   394  bool AesCFBDecrypt(byte* key, int in_size, byte* in, int iv_size, byte* iv,
   395                     int* out_size, byte* out) {
   396    byte last_cipher[32];
   397    byte cipher_block[32];
   398    int size = 0;
   399    int current_size;
   400  
   401    AES_KEY ectx;
   402    AES_set_encrypt_key(key, 128, &ectx);
   403  
   404    // Don't write iv, called already knows it
   405    if(iv_size != AESBLKSIZE) return false;
   406    memcpy(last_cipher, iv, AESBLKSIZE);
   407  
   408    while (in_size > 0) {
   409      if ((size + AESBLKSIZE) > *out_size) return false; 
   410      // P[i] = C[i] ^ E(K, C[i-1])
   411      AES_encrypt(last_cipher, cipher_block, &ectx);
   412      if (in_size >= AESBLKSIZE)
   413        current_size = AESBLKSIZE;
   414      else
   415        current_size = in_size;
   416      XorBlocks(current_size, cipher_block, in, out);
   417      memcpy(last_cipher, in, current_size);
   418      out += current_size;
   419      size += current_size;
   420      in += current_size;
   421      in_size -= current_size;
   422    }
   423    *out_size = size;
   424    return true;
   425  }
   426  
   427  bool VerifyX509CertificateChain(X509* cacert, X509* cert) {
   428    X509_STORE_CTX *store_ctx = X509_STORE_CTX_new();
   429    X509_STORE *store = X509_STORE_new();
   430    X509_STORE_add_cert(store, cacert);
   431    // int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, STACK_OF(X509) *chain);
   432    X509_STORE_CTX_init(store_ctx, store, cacert, nullptr);
   433    int ret = X509_verify_cert(store_ctx);
   434    if (ret <= 0)
   435      printf("Error: %s\n", X509_verify_cert_error_string(store_ctx->error));
   436    return ret;
   437  }
   438  
   439  SslChannel::SslChannel() {
   440    fd_ = -1;
   441    ssl_ctx_ = nullptr;
   442    ssl_ = nullptr;
   443    peer_cert_ = nullptr;
   444    store_ = nullptr;
   445    private_key_ = nullptr;
   446  }
   447  
   448  SslChannel::~SslChannel() {
   449    if (fd_ > 0) {
   450      close(fd_);
   451    }
   452    fd_ = -1;
   453    // clear private_key_;
   454  #if 0
   455    // Doesn't need to be freed, context free takes care of it.
   456    if (ssl_ != nullptr) {
   457      SSL_free(ssl_);
   458    }
   459    ssl_ = nullptr;
   460  #endif
   461    if (peer_cert_ != nullptr) {
   462      X509_free(peer_cert_);
   463    }
   464    peer_cert_ = nullptr;
   465    if (ssl_ctx_ != nullptr) {
   466      SSL_CTX_free(ssl_ctx_);
   467    }
   468    ssl_ctx_ = nullptr;
   469    if (store_ != nullptr) {
   470      X509_STORE_free(store_);
   471    }
   472    store_ = nullptr;
   473  }
   474  
   475  int SslChannel::CreateServerSocket(string& address, string& port) {
   476    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
   477    struct sockaddr_in dest_addr;
   478    uint16_t s_port = atoi(port.c_str());
   479    memset((byte*)&dest_addr, 0, sizeof(dest_addr));
   480  
   481    dest_addr.sin_family = AF_INET;
   482    dest_addr.sin_port = htons(s_port);
   483    dest_addr.sin_addr.s_addr = INADDR_ANY;
   484    inet_aton(address.c_str(), &dest_addr.sin_addr);
   485  
   486    if (bind(sockfd, (struct sockaddr*)&dest_addr, sizeof(dest_addr)) < 0) {
   487      printf("Unable to bind\n");
   488      return -1;
   489    }
   490  
   491    if (listen(sockfd, 1) < 0) {
   492      printf("Unable to listen\n");
   493      return -1;
   494    }
   495    return sockfd;
   496  }
   497  
   498  
   499  int SslChannel::CreateClientSocket(string& addr, string& port) {
   500    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
   501    struct sockaddr_in dest_addr;
   502    uint16_t s_port = atoi(port.c_str());
   503    memset((byte*)&dest_addr, 0, sizeof(dest_addr));
   504  
   505    dest_addr.sin_family = AF_INET;
   506    dest_addr.sin_port = htons(s_port);
   507    dest_addr.sin_addr.s_addr = INADDR_ANY;
   508    inet_aton(addr.c_str(), &dest_addr.sin_addr);
   509  
   510    if (connect(sockfd, (struct sockaddr *) &dest_addr,
   511                sizeof(struct sockaddr)) == -1) {
   512      printf("Error: Cannot connect to host\n");
   513      return -1;
   514    }
   515    return sockfd;
   516  }
   517  
   518  bool SslChannel::InitServerSslChannel(string& network, string& address,
   519                  string& port, X509* policyCert, X509* programCert,
   520                  string& keyType, EVP_PKEY* privateKey, int verify) {
   521     SSL_library_init();
   522     OpenSSL_add_all_algorithms();
   523     ERR_load_crypto_strings();
   524  
   525    // I'm a server.
   526    server_role_ = true;
   527  
   528    if (privateKey == nullptr) {
   529      printf("Private key is null.\n");
   530      return false;
   531    }
   532  
   533    // Create socket and contexts.
   534    fd_ = CreateServerSocket(address, port);
   535    if(fd_ <= 0) {
   536      printf("CreateServerSocket failed.\n");
   537      return false;
   538    }
   539  
   540    ssl_ctx_ = SSL_CTX_new(TLSv1_2_server_method());
   541    if (ssl_ctx_ == nullptr) {
   542      printf("SSL_CTX_new failed(server).\n");
   543      ERR_print_errors_fp(stderr);
   544      return false;
   545    }
   546  
   547    SSL_CTX_clear_extra_chain_certs(ssl_ctx_);
   548    private_key_ = privateKey;
   549    SSL_CTX_use_certificate(ssl_ctx_, programCert);
   550    if (EVP_PKEY_id(private_key_) == EVP_PKEY_EC) {
   551      if (!SSL_CTX_set_tmp_ecdh(ssl_ctx_, EVP_PKEY_get1_EC_KEY(private_key_))) {
   552         printf("SSL_CTX_set_tmp_ecdh failed.\n");
   553         return false;
   554      }
   555      SSL_CTX_set_options(ssl_ctx_, SSL_OP_SINGLE_ECDH_USE);
   556    }
   557    if(SSL_CTX_use_PrivateKey(ssl_ctx_, private_key_) <= 0) {
   558      printf("SSL_CTX_use_PrivateKey failed.\n");
   559      ERR_print_errors_fp(stderr);
   560      return false;
   561    }
   562  
   563    // Setup verification stuff.
   564    switch(verify) {
   565      case SSL_NO_SERVER_VERIFY_NO_CLIENT_AUTH:
   566      case SSL_NO_SERVER_VERIFY_NO_CLIENT_VERIFY:
   567      case SSL_SERVER_VERIFY_NO_CLIENT_VERIFY:
   568        SSL_CTX_set_verify(ssl_ctx_, SSL_VERIFY_NONE, nullptr);
   569        SSL_CTX_set_verify_depth(ssl_ctx_, 3);
   570        break;
   571      case SSL_SERVER_VERIFY_CLIENT_VERIFY:
   572        SSL_CTX_add_extra_chain_cert(ssl_ctx_, programCert);
   573        SSL_CTX_add_extra_chain_cert(ssl_ctx_, policyCert);
   574        store_ = X509_STORE_new();
   575        if (store_ == nullptr) {
   576          printf("X509_STORE_new failed.\n");
   577          return false;
   578        }
   579        X509_STORE_add_cert(store_, policyCert);
   580        SSL_CTX_set_cert_store(ssl_ctx_, store_);
   581        SSL_CTX_set_verify(ssl_ctx_,
   582            SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
   583        SSL_CTX_set_verify_depth(ssl_ctx_, 3);
   584        break;
   585      default:
   586        printf("Unknown verification mode.\n");
   587        return false;
   588    }
   589    return true;
   590  }
   591  
   592  bool SslChannel::InitClientSslChannel(string& network, string& address,
   593                  string& port, X509* policyCert, X509* programCert,
   594                  string& keyType, EVP_PKEY* privateKey, int verify) {
   595     SSL_library_init();
   596     OpenSSL_add_all_algorithms();
   597     ERR_load_crypto_strings();
   598  
   599    // I'm a client.
   600    server_role_ = false;
   601  
   602    // Create socket and contexts.
   603    fd_ = CreateClientSocket(address, port);
   604    if(fd_ <= 0) {
   605      printf("CreateClientSocket failed.\n");
   606      return false;
   607    }
   608  
   609    ssl_ctx_ = SSL_CTX_new(TLSv1_2_client_method());
   610    if (ssl_ctx_ == nullptr) {
   611      printf("SSL_CTX_new failed(client).\n");
   612      return false;
   613    }
   614    SSL_CTX_clear_extra_chain_certs(ssl_ctx_);
   615    if (privateKey == nullptr) {
   616      printf("Private key is null\n");
   617      return false;
   618    }
   619    private_key_ = privateKey;
   620  
   621    // Setup verification stuff.
   622    switch(verify) {
   623      case SSL_NO_SERVER_VERIFY_NO_CLIENT_AUTH:
   624        SSL_CTX_set_verify(ssl_ctx_, SSL_VERIFY_NONE, nullptr);
   625        SSL_CTX_set_verify_depth(ssl_ctx_, 3);
   626        break;
   627      case SSL_NO_SERVER_VERIFY_NO_CLIENT_VERIFY:
   628      case SSL_SERVER_VERIFY_NO_CLIENT_VERIFY:
   629      case SSL_SERVER_VERIFY_CLIENT_VERIFY:
   630        if (privateKey == nullptr) {
   631          printf("Private key is null\n");
   632          return false;
   633        }
   634        if (EVP_PKEY_id(private_key_) == EVP_PKEY_EC) {
   635          if (!SSL_CTX_set_tmp_ecdh(ssl_ctx_,
   636                  EVP_PKEY_get1_EC_KEY(private_key_))) {
   637            printf("SSL_CTX_set_tmp_ecdh failed.\n");
   638            return false;
   639          }
   640          SSL_CTX_set_options(ssl_ctx_, SSL_OP_SINGLE_ECDH_USE);
   641        }
   642        if(SSL_CTX_use_PrivateKey(ssl_ctx_, private_key_) <= 0) {
   643          printf("SSL_CTX_use_PrivateKey failed.\n");
   644          ERR_print_errors_fp(stderr);
   645          return false;
   646        }
   647        SSL_CTX_use_certificate(ssl_ctx_, programCert);
   648        SSL_CTX_add_extra_chain_cert(ssl_ctx_, programCert);
   649        SSL_CTX_add_extra_chain_cert(ssl_ctx_, policyCert);
   650        store_ = X509_STORE_new();
   651        if (store_ == nullptr) {
   652          printf("X509_STORE_new failed.\n");
   653          return false;
   654        }
   655        X509_STORE_add_cert(store_, policyCert);
   656        SSL_CTX_set_cert_store(ssl_ctx_, store_);
   657        SSL_CTX_set_verify(ssl_ctx_,
   658          SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
   659        SSL_CTX_set_verify_depth(ssl_ctx_, 3);
   660        if (verify == SSL_NO_SERVER_VERIFY_NO_CLIENT_VERIFY)
   661          SSL_CTX_set_verify(ssl_ctx_, SSL_VERIFY_NONE, nullptr); 
   662        break;
   663      default:
   664        printf("Unknown verification mode.\n");
   665        return false;
   666    }
   667  
   668    ssl_ = SSL_new(ssl_ctx_);
   669    if (ssl_ == nullptr) {
   670      printf("SSL_new failed(client).\n");
   671      return false;
   672    }
   673  
   674    SSL_set_fd(ssl_, fd_);
   675    SSL_set_connect_state(ssl_);
   676  
   677    // Connect.
   678    if (SSL_connect(ssl_) != 1) {
   679      printf("SSL_connect failed.\n");
   680      ERR_print_errors_fp(stderr);
   681      return false;
   682    }
   683    peer_cert_ = SSL_get_peer_certificate(ssl_);
   684    return true;
   685  }
   686  
   687  bool SslChannel::ServerLoop(void(*server_loop)(SslChannel*,  SSL*, int)) {
   688    bool fContinue = true;
   689    printf("ServerLoop\n");
   690  
   691    while(fContinue) {
   692      struct sockaddr_in addr;
   693      uint len = sizeof(addr);
   694      memset((byte*)&addr, 0, len);
   695  
   696      int client = accept(fd_, (struct sockaddr*)&addr, &len);
   697      if (client < 0) {
   698        printf("Unable to accept\n");
   699        printf("ERR: %s\n", ERR_lib_error_string(ERR_get_error()));
   700        continue;
   701      }
   702  
   703      SSL* ssl = SSL_new(ssl_ctx_);
   704      if (private_key_ == nullptr) {
   705        printf("private_key_ is null.\n");
   706        return false;
   707      }
   708      SSL_set_fd(ssl, client);
   709      SSL_set_accept_state(ssl);
   710      if (SSL_accept(ssl) <= 0) {
   711        printf("Unable to ssl_accept\n");
   712        ERR_print_errors_fp(stderr);
   713        continue;
   714      } 
   715      server_loop(this, ssl, client);
   716      // thread t(server_loop, this, ssl, client);
   717    }
   718    return true;
   719  }
   720  
   721  void SslChannel::Close() {
   722    if (fd_ > 0) {
   723      close(fd_);
   724    }
   725    fd_ = -1;
   726    if (ssl_ != nullptr) {
   727      SSL_free(ssl_);
   728    }
   729    ssl_ = nullptr;
   730    if (peer_cert_ != nullptr) {
   731      X509_free(peer_cert_);
   732    }
   733    peer_cert_ = nullptr;
   734    if (ssl_ctx_ != nullptr) {
   735      SSL_CTX_free(ssl_ctx_);
   736    }
   737    ssl_ctx_ = nullptr;
   738    if (store_ != nullptr) {
   739      X509_STORE_free(store_);
   740    }
   741    store_ = nullptr;
   742  }
   743  
   744  X509* SslChannel::GetPeerCert() {
   745    return peer_cert_;
   746  }
   747  
   748  int SslMessageRead(SSL* ssl, int size, byte* buf) {
   749    byte new_buf[8192];
   750    int tmp_size = SslRead(ssl, size, new_buf);
   751    if (tmp_size <= 0)
   752      return tmp_size;
   753    int real_size = __builtin_bswap32(*((int*)new_buf));
   754    if (tmp_size == sizeof(int)) {
   755      return SslRead(ssl, real_size, buf);
   756    }
   757    memcpy(buf, &new_buf[4], real_size);
   758    return real_size;
   759  }
   760  
   761  int SslMessageWrite(SSL* ssl, int size, byte* buf) {
   762    // write 32 bit size and buffer
   763    int big_endian_size = __builtin_bswap32(size);
   764    byte new_buf[8192];
   765    memcpy(new_buf, (byte*)&big_endian_size, sizeof(int));
   766    memcpy(&new_buf[sizeof(int)], buf, size);
   767    return SslWrite(ssl, size + sizeof(int), new_buf) - sizeof(int);
   768  }
   769  
   770  int SslRead(SSL* ssl, int size, byte* buf) {
   771    return SSL_read(ssl, buf, size);
   772  }
   773  
   774  int SslWrite(SSL* ssl, int size, byte* buf) {
   775    return SSL_write(ssl, buf, size);
   776  }
   777  
   778  // TODO: consider using std::to_string
   779  int NumHexInBytes(int size, byte* in) { return 2 * size; }
   780  
   781  int NumBytesInHex(char* in) {
   782    if (in == nullptr)
   783      return -1;
   784    int len = strlen(in);
   785    return ((len + 1) / 2);
   786  }
   787  
   788  char ValueToHex(byte x) {
   789    if (x >= 0 && x <= 9) {
   790      return x + '0';
   791    } else if (x >= 10 && x <= 15) {
   792      return x - 10 + 'a';
   793    } else {
   794      return ' ';
   795    }
   796  }
   797  
   798  byte HexToValue(char x) {
   799    if (x >= '0' && x <= '9') {
   800      return x - '0';
   801    } else if (x >= 'a' && x <= 'f') {
   802      return x + 10 - 'a';
   803    } else {
   804      return 0;
   805    }
   806  }
   807  
   808  string* ByteToHexLeftToRight(int size, byte* in) {
   809    if (in == nullptr)
   810      return nullptr;
   811    int n = NumHexInBytes(size, in);
   812    string* out = new string(n, 0);
   813    char* str = (char*)out->c_str();
   814    byte a, b;
   815  
   816    while (size > 0) {
   817      a = (*in) >> 4;
   818      b = (*in) & 0xf;
   819      in++;
   820      *(str++) = ValueToHex(a);
   821      *(str++) = ValueToHex(b);
   822      size--;
   823    }
   824    return out;
   825  }
   826  
   827  int HexToByteLeftToRight(char* in, int size, byte* out) {
   828    if (in == nullptr)
   829      return -1;
   830    int n = NumBytesInHex(in);
   831    int m = strlen(in);
   832    byte a, b;
   833  
   834    if (n > size) {
   835      return -1;
   836    }
   837    while (m > 0) {
   838      a = HexToValue(*(in++));
   839      b = HexToValue(*(in++));
   840      *(out++) = (a << 4) | b;
   841      m -= 2;
   842    }
   843    return n;
   844  }
   845  
   846  string* ByteToHexRightToLeft(int size, byte* in) {
   847    if (in == nullptr)
   848      return nullptr;
   849    int n = NumHexInBytes(size, in);
   850    string* out = new string(n, 0);
   851    char* str = (char*)out->c_str();
   852    byte a, b;
   853  
   854    in += size - 1;
   855    while (size > 0) {
   856      a = (*in) >> 4;
   857      b = (*in) & 0xf;
   858      in--;
   859      *(str++) = ValueToHex(a);
   860      *(str++) = ValueToHex(b);
   861      size--;
   862    }
   863    return out;
   864  }
   865  
   866  
   867  int HexToByteRightToLeft(char* in, int size, byte* out) {
   868    if (in == nullptr) {
   869      return -1;
   870    }
   871    int n = NumBytesInHex(in);
   872    int m = strlen(in);
   873    byte a, b;
   874  
   875    out += n - 1;
   876    if (m < 0) {
   877      return -1;
   878    }
   879    while (m > 0) {
   880      a = HexToValue(*(in++));
   881      b = HexToValue(*(in++));
   882      *(out--) = (a << 4) | b;
   883      m -= 2;
   884    }
   885    return n;
   886  }