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 }