1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef _SSL_H_ 16 #define _SSL_H_ 17 18 #ifdef __cplusplus 19 extern "C" { 20 #endif 21 22 #include <stdlib.h> 23 #include "ssl_x509.h" 24 #include "ssl_pkey.h" 25 26 /* 27 { 28 */ 29 30 #define SSL_CB_ALERT 0x4000 31 32 #define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT (1 << 0) 33 #define X509_CHECK_FLAG_NO_WILDCARDS (1 << 1) 34 #define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS (1 << 2) 35 #define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS (1 << 3) 36 #define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS (1 << 4) 37 38 mbedtls_x509_crt * 39 ssl_ctx_get_mbedtls_x509_crt(SSL_CTX *ssl_ctx); 40 41 mbedtls_x509_crt * 42 ssl_get_peer_mbedtls_x509_crt(SSL *ssl); 43 44 int SSL_set_sni_callback(SSL *ssl, int(*cb)(void *, mbedtls_ssl_context *, 45 const unsigned char *, size_t), void *param); 46 47 void SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); 48 49 int SSL_CTX_add_client_CA_ASN1(SSL_CTX *ssl, int len, 50 const unsigned char *d); 51 52 SSL *SSL_SSL_from_mbedtls_ssl_context(mbedtls_ssl_context *msc); 53 54 /** 55 * @brief create a SSL context 56 * 57 * @param method - the SSL context method point 58 * 59 * @return the context point 60 */ 61 SSL_CTX* SSL_CTX_new(const SSL_METHOD *method); 62 63 /** 64 * @brief free a SSL context 65 * 66 * @param method - the SSL context point 67 * 68 * @return none 69 */ 70 void SSL_CTX_free(SSL_CTX *ctx); 71 72 /** 73 * @brief create a SSL 74 * 75 * @param ctx - the SSL context point 76 * 77 * @return the SSL point 78 */ 79 SSL* SSL_new(SSL_CTX *ctx); 80 81 /** 82 * @brief free the SSL 83 * 84 * @param ssl - the SSL point 85 * 86 * @return none 87 */ 88 void SSL_free(SSL *ssl); 89 90 /** 91 * @brief connect to the remote SSL server 92 * 93 * @param ssl - the SSL point 94 * 95 * @return result 96 * 1 : OK 97 * -1 : failed 98 */ 99 int SSL_connect(SSL *ssl); 100 101 /** 102 * @brief accept the remote connection 103 * 104 * @param ssl - the SSL point 105 * 106 * @return result 107 * 1 : OK 108 * -1 : failed 109 */ 110 int SSL_accept(SSL *ssl); 111 112 /** 113 * @brief read data from to remote 114 * 115 * @param ssl - the SSL point which has been connected 116 * @param buffer - the received data buffer point 117 * @param len - the received data length 118 * 119 * @return result 120 * > 0 : OK, and return received data bytes 121 * = 0 : connection is closed 122 * < 0 : an error catch 123 */ 124 int SSL_read(SSL *ssl, void *buffer, int len); 125 126 /** 127 * @brief send the data to remote 128 * 129 * @param ssl - the SSL point which has been connected 130 * @param buffer - the send data buffer point 131 * @param len - the send data length 132 * 133 * @return result 134 * > 0 : OK, and return sent data bytes 135 * = 0 : connection is closed 136 * < 0 : an error catch 137 */ 138 int SSL_write(SSL *ssl, const void *buffer, int len); 139 140 /** 141 * @brief get the verifying result of the SSL certification 142 * 143 * @param ssl - the SSL point 144 * 145 * @return the result of verifying 146 */ 147 long SSL_get_verify_result(const SSL *ssl); 148 149 /** 150 * @brief shutdown the connection 151 * 152 * @param ssl - the SSL point 153 * 154 * @return result 155 * 1 : OK 156 * 0 : shutdown is not finished 157 * -1 : an error catch 158 */ 159 int SSL_shutdown(SSL *ssl); 160 161 /** 162 * @brief bind the socket file description into the SSL 163 * 164 * @param ssl - the SSL point 165 * @param fd - socket handle 166 * 167 * @return result 168 * 1 : OK 169 * 0 : failed 170 */ 171 int SSL_set_fd(SSL *ssl, int fd); 172 173 /** 174 * @brief These functions load the private key into the SSL_CTX or SSL object 175 * 176 * @param ctx - the SSL context point 177 * @param pkey - private key object point 178 * 179 * @return result 180 * 1 : OK 181 * 0 : failed 182 */ 183 int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); 184 185 /** 186 * @brief These functions load the certification into the SSL_CTX or SSL object 187 * 188 * @param ctx - the SSL context point 189 * @param pkey - certification object point 190 * 191 * @return result 192 * 1 : OK 193 * 0 : failed 194 */ 195 int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); 196 197 /** 198 * @brief create the target SSL context client method 199 * 200 * @param none 201 * 202 * @return the SSLV2.3 version SSL context client method 203 */ 204 const SSL_METHOD* SSLv23_client_method(void); 205 206 /** 207 * @brief create the target SSL context client method 208 * 209 * @param none 210 * 211 * @return the TLSV1.0 version SSL context client method 212 */ 213 const SSL_METHOD* TLSv1_client_method(void); 214 215 /** 216 * @brief create the target SSL context client method 217 * 218 * @param none 219 * 220 * @return the SSLV1.0 version SSL context client method 221 */ 222 const SSL_METHOD* SSLv3_client_method(void); 223 224 /** 225 * @brief create the target SSL context client method 226 * 227 * @param none 228 * 229 * @return the TLSV1.1 version SSL context client method 230 */ 231 const SSL_METHOD* TLSv1_1_client_method(void); 232 233 /** 234 * @brief create the target SSL context client method 235 * 236 * @param none 237 * 238 * @return the TLSV1.2 version SSL context client method 239 */ 240 const SSL_METHOD* TLSv1_2_client_method(void); 241 242 /** 243 * @brief create the target SSL context server method 244 * 245 * @param none 246 * 247 * @return the TLS any version SSL context client method 248 */ 249 const SSL_METHOD* TLS_client_method(void); 250 251 /** 252 * @brief create the target SSL context server method 253 * 254 * @param none 255 * 256 * @return the SSLV2.3 version SSL context server method 257 */ 258 const SSL_METHOD* SSLv23_server_method(void); 259 260 /** 261 * @brief create the target SSL context server method 262 * 263 * @param none 264 * 265 * @return the TLSV1.1 version SSL context server method 266 */ 267 const SSL_METHOD* TLSv1_1_server_method(void); 268 269 /** 270 * @brief create the target SSL context server method 271 * 272 * @param none 273 * 274 * @return the TLSV1.2 version SSL context server method 275 */ 276 const SSL_METHOD* TLSv1_2_server_method(void); 277 278 /** 279 * @brief create the target SSL context server method 280 * 281 * @param none 282 * 283 * @return the TLSV1.0 version SSL context server method 284 */ 285 const SSL_METHOD* TLSv1_server_method(void); 286 287 /** 288 * @brief create the target SSL context server method 289 * 290 * @param none 291 * 292 * @return the SSLV3.0 version SSL context server method 293 */ 294 const SSL_METHOD* SSLv3_server_method(void); 295 296 /** 297 * @brief create the target SSL context server method 298 * 299 * @param none 300 * 301 * @return the TLS any version SSL context server method 302 */ 303 const SSL_METHOD* TLS_server_method(void); 304 305 306 /** 307 * @brief set the SSL context ALPN select callback function 308 * 309 * @param ctx - SSL context point 310 * @param cb - ALPN select callback function 311 * @param arg - ALPN select callback function entry private data point 312 * 313 * @return none 314 */ 315 void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, next_proto_cb cb, 316 void *arg); 317 318 void SSL_set_alpn_select_cb(SSL *ssl, void *arg); 319 320 /** 321 * @brief set the SSL context ALPN select protocol 322 * 323 * @param ctx - SSL context point 324 * @param protos - ALPN protocol name 325 * @param protos_len - ALPN protocol name bytes 326 * 327 * @return result 328 * 0 : OK 329 * 1 : failed 330 */ 331 int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, unsigned int protos_len); 332 333 /** 334 * @brief set the SSL context next ALPN select callback function 335 * 336 * @param ctx - SSL context point 337 * @param cb - ALPN select callback function 338 * @param arg - ALPN select callback function entry private data point 339 * 340 * @return none 341 */ 342 void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, 343 int (*cb) (SSL *ssl, 344 unsigned char **out, 345 unsigned char *outlen, 346 const unsigned char *in, 347 unsigned int inlen, 348 void *arg), 349 void *arg); 350 351 void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, 352 unsigned int *len); 353 354 void _ssl_set_alpn_list(const SSL *ssl); 355 356 /** 357 * @brief get SSL error code 358 * 359 * @param ssl - SSL point 360 * @param ret_code - SSL return code 361 * 362 * @return SSL error number 363 */ 364 int SSL_get_error(const SSL *ssl, int ret_code); 365 366 /** 367 * @brief clear the SSL error code 368 * 369 * @param none 370 * 371 * @return none 372 */ 373 void ERR_clear_error(void); 374 375 /** 376 * @brief get the current SSL error code 377 * 378 * @param none 379 * 380 * @return current SSL error number 381 */ 382 int ERR_get_error(void); 383 384 /** 385 * @brief register the SSL error strings 386 * 387 * @param none 388 * 389 * @return none 390 */ 391 void ERR_load_SSL_strings(void); 392 393 /** 394 * @brief initialize the SSL library 395 * 396 * @param none 397 * 398 * @return none 399 */ 400 void SSL_library_init(void); 401 402 /** 403 * @brief generates a human-readable string representing the error code e 404 * and store it into the "ret" point memory 405 * 406 * @param e - error code 407 * @param ret - memory point to store the string 408 * 409 * @return the result string point 410 */ 411 char *ERR_error_string(unsigned long e, char *ret); 412 413 /** 414 * @brief add the SSL context option 415 * 416 * @param ctx - SSL context point 417 * @param opt - new SSL context option 418 * 419 * @return the SSL context option 420 */ 421 unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt); 422 423 /** 424 * @brief add the SSL context mode 425 * 426 * @param ctx - SSL context point 427 * @param mod - new SSL context mod 428 * 429 * @return result 430 * 1 : OK 431 * 0 : failed 432 */ 433 int SSL_CTX_set_mode(SSL_CTX *ctx, int mod); 434 435 /* 436 } 437 */ 438 439 /** 440 * @brief perform the SSL handshake 441 * 442 * @param ssl - SSL point 443 * 444 * @return result 445 * 1 : OK 446 * 0 : failed 447 * -1 : a error catch 448 */ 449 int SSL_do_handshake(SSL *ssl); 450 451 /** 452 * @brief get the SSL current version 453 * 454 * @param ssl - SSL point 455 * 456 * @return the version string 457 */ 458 const char *SSL_get_version(const SSL *ssl); 459 460 /** 461 * @brief set the SSL context version 462 * 463 * @param ctx - SSL context point 464 * @param meth - SSL method point 465 * 466 * @return result 467 * 1 : OK 468 * 0 : failed 469 */ 470 int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); 471 472 /** 473 * @brief get the bytes numbers which are to be read 474 * 475 * @param ssl - SSL point 476 * 477 * @return bytes number 478 */ 479 int SSL_pending(const SSL *ssl); 480 481 /** 482 * @brief check if SSL want nothing 483 * 484 * @param ssl - SSL point 485 * 486 * @return result 487 * 0 : false 488 * 1 : true 489 */ 490 int SSL_want_nothing(const SSL *ssl); 491 492 /** 493 * @brief check if SSL want to read 494 * 495 * @param ssl - SSL point 496 * 497 * @return result 498 * 0 : false 499 * 1 : true 500 */ 501 int SSL_want_read(const SSL *ssl); 502 503 /** 504 * @brief check if SSL want to write 505 * 506 * @param ssl - SSL point 507 * 508 * @return result 509 * 0 : false 510 * 1 : true 511 */ 512 int SSL_want_write(const SSL *ssl); 513 514 /** 515 * @brief get the SSL context current method 516 * 517 * @param ctx - SSL context point 518 * 519 * @return the SSL context current method 520 */ 521 const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); 522 523 /** 524 * @brief get the SSL current method 525 * 526 * @param ssl - SSL point 527 * 528 * @return the SSL current method 529 */ 530 const SSL_METHOD *SSL_get_ssl_method(SSL *ssl); 531 532 /** 533 * @brief set the SSL method 534 * 535 * @param ssl - SSL point 536 * @param meth - SSL method point 537 * 538 * @return result 539 * 1 : OK 540 * 0 : failed 541 */ 542 int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method); 543 544 /** 545 * @brief add CA client certification into the SSL 546 * 547 * @param ssl - SSL point 548 * @param x - CA certification point 549 * 550 * @return result 551 * 1 : OK 552 * 0 : failed 553 */ 554 int SSL_add_client_CA(SSL *ssl, X509 *x); 555 556 /** 557 * @brief add CA client certification into the SSL context 558 * 559 * @param ctx - SSL context point 560 * @param x - CA certification point 561 * 562 * @return result 563 * 1 : OK 564 * 0 : failed 565 */ 566 int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); 567 568 /** 569 * @brief set the SSL CA certification list 570 * 571 * @param ssl - SSL point 572 * @param name_list - CA certification list 573 * 574 * @return none 575 */ 576 void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list); 577 578 /** 579 * @brief set the SSL context CA certification list 580 * 581 * @param ctx - SSL context point 582 * @param name_list - CA certification list 583 * 584 * @return none 585 */ 586 void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); 587 588 /** 589 * @briefget the SSL CA certification list 590 * 591 * @param ssl - SSL point 592 * 593 * @return CA certification list 594 */ 595 STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl); 596 597 /** 598 * @brief get the SSL context CA certification list 599 * 600 * @param ctx - SSL context point 601 * 602 * @return CA certification list 603 */ 604 STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx); 605 606 /** 607 * @brief get the SSL certification point 608 * 609 * @param ssl - SSL point 610 * 611 * @return SSL certification point 612 */ 613 X509 *SSL_get_certificate(const SSL *ssl); 614 615 /** 616 * @brief get the SSL private key point 617 * 618 * @param ssl - SSL point 619 * 620 * @return SSL private key point 621 */ 622 EVP_PKEY *SSL_get_privatekey(const SSL *ssl); 623 624 /** 625 * @brief set the SSL information callback function 626 * 627 * @param ssl - SSL point 628 * @param cb - information callback function 629 * 630 * @return none 631 */ 632 void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)); 633 634 /** 635 * @brief get the SSL state 636 * 637 * @param ssl - SSL point 638 * 639 * @return SSL state 640 */ 641 OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); 642 643 /** 644 * @brief set the SSL context read buffer length 645 * 646 * @param ctx - SSL context point 647 * @param len - read buffer length 648 * 649 * @return none 650 */ 651 void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); 652 653 /** 654 * @brief set the SSL read buffer length 655 * 656 * @param ssl - SSL point 657 * @param len - read buffer length 658 * 659 * @return none 660 */ 661 void SSL_set_default_read_buffer_len(SSL *ssl, size_t len); 662 663 /** 664 * @brief set the SSL security level 665 * 666 * @param ssl - SSL point 667 * @param level - security level 668 * 669 * @return none 670 */ 671 void SSL_set_security_level(SSL *ssl, int level); 672 673 /** 674 * @brief get the SSL security level 675 * 676 * @param ssl - SSL point 677 * 678 * @return security level 679 */ 680 int SSL_get_security_level(const SSL *ssl); 681 682 /** 683 * @brief get the SSL verifying mode of the SSL context 684 * 685 * @param ctx - SSL context point 686 * 687 * @return verifying mode 688 */ 689 int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); 690 691 /** 692 * @brief get the SSL verifying depth of the SSL context 693 * 694 * @param ctx - SSL context point 695 * 696 * @return verifying depth 697 */ 698 int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); 699 700 /** 701 * @brief set the SSL context verifying of the SSL context 702 * 703 * @param ctx - SSL context point 704 * @param mode - verifying mode 705 * @param verify_callback - verifying callback function 706 * 707 * @return none 708 */ 709 void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); 710 711 /** 712 * @brief set the SSL verifying of the SSL context 713 * 714 * @param ctx - SSL point 715 * @param mode - verifying mode 716 * @param verify_callback - verifying callback function 717 * 718 * @return none 719 */ 720 void SSL_set_verify(SSL *s, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); 721 722 /** 723 * @brief set the SSL verify depth of the SSL context 724 * 725 * @param ctx - SSL context point 726 * @param depth - verifying depth 727 * 728 * @return none 729 */ 730 void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); 731 732 /** 733 * @brief certification verifying callback function 734 * 735 * @param preverify_ok - verifying result 736 * @param x509_ctx - X509 certification point 737 * 738 * @return verifying result 739 */ 740 int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx); 741 742 /** 743 * @brief set the session timeout time 744 * 745 * @param ctx - SSL context point 746 * @param t - new session timeout time 747 * 748 * @return old session timeout time 749 */ 750 long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); 751 752 /** 753 * @brief get the session timeout time 754 * 755 * @param ctx - SSL context point 756 * 757 * @return current session timeout time 758 */ 759 long SSL_CTX_get_timeout(const SSL_CTX *ctx); 760 761 /** 762 * @brief set the SSL context cipher through the list string 763 * 764 * @param ctx - SSL context point 765 * @param str - cipher controller list string 766 * 767 * @return result 768 * 1 : OK 769 * 0 : failed 770 */ 771 int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); 772 773 /** 774 * @brief set the SSL cipher through the list string 775 * 776 * @param ssl - SSL point 777 * @param str - cipher controller list string 778 * 779 * @return result 780 * 1 : OK 781 * 0 : failed 782 */ 783 int SSL_set_cipher_list(SSL *ssl, const char *str); 784 785 /** 786 * @brief get the SSL cipher list string 787 * 788 * @param ssl - SSL point 789 * 790 * @return cipher controller list string 791 */ 792 const char *SSL_get_cipher_list(const SSL *ssl, int n); 793 794 /** 795 * @brief get the SSL cipher 796 * 797 * @param ssl - SSL point 798 * 799 * @return current cipher 800 */ 801 const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl); 802 803 /** 804 * @brief get the SSL cipher string 805 * 806 * @param ssl - SSL point 807 * 808 * @return cipher string 809 */ 810 const char *SSL_get_cipher(const SSL *ssl); 811 812 /** 813 * @brief get the SSL context object X509 certification storage 814 * 815 * @param ctx - SSL context point 816 * 817 * @return x509 certification storage 818 */ 819 X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); 820 821 /** 822 * @brief set the SSL context object X509 certification store 823 * 824 * @param ctx - SSL context point 825 * @param store - X509 certification store 826 * 827 * @return none 828 */ 829 void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store); 830 831 /** 832 * @brief get the SSL specifical statement 833 * 834 * @param ssl - SSL point 835 * 836 * @return specifical statement 837 */ 838 int SSL_want(const SSL *ssl); 839 840 /** 841 * @brief check if the SSL is SSL_X509_LOOKUP state 842 * 843 * @param ssl - SSL point 844 * 845 * @return result 846 * 1 : OK 847 * 0 : failed 848 */ 849 int SSL_want_x509_lookup(const SSL *ssl); 850 851 /** 852 * @brief reset the SSL 853 * 854 * @param ssl - SSL point 855 * 856 * @return result 857 * 1 : OK 858 * 0 : failed 859 */ 860 int SSL_clear(SSL *ssl); 861 862 /** 863 * @brief get the socket handle of the SSL 864 * 865 * @param ssl - SSL point 866 * 867 * @return result 868 * >= 0 : yes, and return socket handle 869 * < 0 : a error catch 870 */ 871 int SSL_get_fd(const SSL *ssl); 872 873 /** 874 * @brief get the read only socket handle of the SSL 875 * 876 * @param ssl - SSL point 877 * 878 * @return result 879 * >= 0 : yes, and return socket handle 880 * < 0 : a error catch 881 */ 882 int SSL_get_rfd(const SSL *ssl); 883 884 /** 885 * @brief get the write only socket handle of the SSL 886 * 887 * @param ssl - SSL point 888 * 889 * @return result 890 * >= 0 : yes, and return socket handle 891 * < 0 : a error catch 892 */ 893 int SSL_get_wfd(const SSL *ssl); 894 895 /** 896 * @brief set the SSL if we can read as many as data 897 * 898 * @param ssl - SSL point 899 * @param yes - enable the function 900 * 901 * @return none 902 */ 903 void SSL_set_read_ahead(SSL *s, int yes); 904 905 /** 906 * @brief set the SSL context if we can read as many as data 907 * 908 * @param ctx - SSL context point 909 * @param yes - enbale the function 910 * 911 * @return none 912 */ 913 void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes); 914 915 /** 916 * @brief get the SSL ahead signal if we can read as many as data 917 * 918 * @param ssl - SSL point 919 * 920 * @return SSL context ahead signal 921 */ 922 int SSL_get_read_ahead(const SSL *ssl); 923 924 /** 925 * @brief get the SSL context ahead signal if we can read as many as data 926 * 927 * @param ctx - SSL context point 928 * 929 * @return SSL context ahead signal 930 */ 931 long SSL_CTX_get_read_ahead(SSL_CTX *ctx); 932 933 /** 934 * @brief check if some data can be read 935 * 936 * @param ssl - SSL point 937 * 938 * @return 939 * 1 : there are bytes to be read 940 * 0 : no data 941 */ 942 int SSL_has_pending(const SSL *ssl); 943 944 /** 945 * @brief load the X509 certification into SSL context 946 * 947 * @param ctx - SSL context point 948 * @param x - X509 certification point 949 * 950 * @return result 951 * 1 : OK 952 * 0 : failed 953 */ 954 int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);//loads the certificate x into ctx 955 956 /** 957 * @brief load the ASN1 certification into SSL context 958 * 959 * @param ctx - SSL context point 960 * @param len - certification length 961 * @param d - data point 962 * 963 * @return result 964 * 1 : OK 965 * 0 : failed 966 */ 967 int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); 968 969 /** 970 * @brief load the certification file into SSL context 971 * 972 * @param ctx - SSL context point 973 * @param file - certification file name 974 * @param type - certification encoding type 975 * 976 * @return result 977 * 1 : OK 978 * 0 : failed 979 */ 980 int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); 981 982 /** 983 * @brief load the certification chain file into SSL context 984 * 985 * @param ctx - SSL context point 986 * @param file - certification chain file name 987 * 988 * @return result 989 * 1 : OK 990 * 0 : failed 991 */ 992 int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); 993 994 995 /** 996 * @brief load the ASN1 private key into SSL context 997 * 998 * @param ctx - SSL context point 999 * @param d - data point 1000 * @param len - private key length 1001 * 1002 * @return result 1003 * 1 : OK 1004 * 0 : failed 1005 */ 1006 int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len);//adds the private key of type pk stored at memory location d (length len) to ctx 1007 1008 /** 1009 * @brief load the private key file into SSL context 1010 * 1011 * @param ctx - SSL context point 1012 * @param file - private key file name 1013 * @param type - private key encoding type 1014 * 1015 * @return result 1016 * 1 : OK 1017 * 0 : failed 1018 */ 1019 int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); 1020 1021 /** 1022 * @brief load the RSA private key into SSL context 1023 * 1024 * @param ctx - SSL context point 1025 * @param x - RSA private key point 1026 * 1027 * @return result 1028 * 1 : OK 1029 * 0 : failed 1030 */ 1031 int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); 1032 1033 /** 1034 * @brief load the RSA ASN1 private key into SSL context 1035 * 1036 * @param ctx - SSL context point 1037 * @param d - data point 1038 * @param len - RSA private key length 1039 * 1040 * @return result 1041 * 1 : OK 1042 * 0 : failed 1043 */ 1044 int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); 1045 1046 /** 1047 * @brief load the RSA private key file into SSL context 1048 * 1049 * @param ctx - SSL context point 1050 * @param file - RSA private key file name 1051 * @param type - private key encoding type 1052 * 1053 * @return result 1054 * 1 : OK 1055 * 0 : failed 1056 */ 1057 int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); 1058 1059 1060 /** 1061 * @brief check if the private key and certification is matched 1062 * 1063 * @param ctx - SSL context point 1064 * 1065 * @return result 1066 * 1 : OK 1067 * 0 : failed 1068 */ 1069 int SSL_CTX_check_private_key(const SSL_CTX *ctx); 1070 1071 /** 1072 * @brief set the SSL context server information 1073 * 1074 * @param ctx - SSL context point 1075 * @param serverinfo - server information string 1076 * @param serverinfo_length - server information length 1077 * 1078 * @return result 1079 * 1 : OK 1080 * 0 : failed 1081 */ 1082 int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, size_t serverinfo_length); 1083 1084 /** 1085 * @brief load the SSL context server infomation file into SSL context 1086 * 1087 * @param ctx - SSL context point 1088 * @param file - server information file 1089 * 1090 * @return result 1091 * 1 : OK 1092 * 0 : failed 1093 */ 1094 int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); 1095 1096 /** 1097 * @brief SSL select next function 1098 * 1099 * @param out - point of output data point 1100 * @param outlen - output data length 1101 * @param in - input data 1102 * @param inlen - input data length 1103 * @param client - client data point 1104 * @param client_len -client data length 1105 * 1106 * @return NPN state 1107 * OPENSSL_NPN_UNSUPPORTED : not support 1108 * OPENSSL_NPN_NEGOTIATED : negotiated 1109 * OPENSSL_NPN_NO_OVERLAP : no overlap 1110 */ 1111 int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, 1112 const unsigned char *in, unsigned int inlen, 1113 const unsigned char *client, unsigned int client_len); 1114 1115 /** 1116 * @brief load the extra certification chain into the SSL context 1117 * 1118 * @param ctx - SSL context point 1119 * @param x509 - X509 certification 1120 * 1121 * @return result 1122 * 1 : OK 1123 * 0 : failed 1124 */ 1125 long SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *); 1126 1127 /** 1128 * @brief control the SSL context 1129 * 1130 * @param ctx - SSL context point 1131 * @param cmd - command 1132 * @param larg - parameter length 1133 * @param parg - parameter point 1134 * 1135 * @return result 1136 * 1 : OK 1137 * 0 : failed 1138 */ 1139 long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg); 1140 1141 /** 1142 * @brief get the SSL context cipher 1143 * 1144 * @param ctx - SSL context point 1145 * 1146 * @return SSL context cipher 1147 */ 1148 STACK *SSL_CTX_get_ciphers(const SSL_CTX *ctx); 1149 1150 /** 1151 * @brief check if the SSL context can read as many as data 1152 * 1153 * @param ctx - SSL context point 1154 * 1155 * @return result 1156 * 1 : OK 1157 * 0 : failed 1158 */ 1159 long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx); 1160 1161 /** 1162 * @brief get the SSL context extra data 1163 * 1164 * @param ctx - SSL context point 1165 * @param idx - index 1166 * 1167 * @return data point 1168 */ 1169 void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx); 1170 1171 /** 1172 * @brief get the SSL context quiet shutdown option 1173 * 1174 * @param ctx - SSL context point 1175 * 1176 * @return quiet shutdown option 1177 */ 1178 int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); 1179 1180 /** 1181 * @brief load the SSL context CA file 1182 * 1183 * @param ctx - SSL context point 1184 * @param CAfile - CA certification file 1185 * @param CApath - CA certification file path 1186 * 1187 * @return result 1188 * 1 : OK 1189 * 0 : failed 1190 */ 1191 int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath); 1192 1193 /** 1194 * @brief add SSL context reference count by '1' 1195 * 1196 * @param ctx - SSL context point 1197 * 1198 * @return result 1199 * 1 : OK 1200 * 0 : failed 1201 */ 1202 int SSL_CTX_up_ref(SSL_CTX *ctx); 1203 1204 /** 1205 * @brief set SSL context application private data 1206 * 1207 * @param ctx - SSL context point 1208 * @param arg - private data 1209 * 1210 * @return result 1211 * 1 : OK 1212 * 0 : failed 1213 */ 1214 int SSL_CTX_set_app_data(SSL_CTX *ctx, void *arg); 1215 1216 /** 1217 * @brief set SSL context client certification callback function 1218 * 1219 * @param ctx - SSL context point 1220 * @param cb - callback function 1221 * 1222 * @return none 1223 */ 1224 void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)); 1225 1226 /** 1227 * @brief set the SSL context if we can read as many as data 1228 * 1229 * @param ctx - SSL context point 1230 * @param m - enable the fuction 1231 * 1232 * @return none 1233 */ 1234 void SSL_CTX_set_default_read_ahead(SSL_CTX *ctx, int m); 1235 1236 /** 1237 * @brief set SSL context default verifying path 1238 * 1239 * @param ctx - SSL context point 1240 * 1241 * @return result 1242 * 1 : OK 1243 * 0 : failed 1244 */ 1245 int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); 1246 1247 /** 1248 * @brief set SSL context default verifying directory 1249 * 1250 * @param ctx - SSL context point 1251 * 1252 * @return result 1253 * 1 : OK 1254 * 0 : failed 1255 */ 1256 int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx); 1257 1258 /** 1259 * @brief set SSL context default verifying file 1260 * 1261 * @param ctx - SSL context point 1262 * 1263 * @return result 1264 * 1 : OK 1265 * 0 : failed 1266 */ 1267 int SSL_CTX_set_default_verify_file(SSL_CTX *ctx); 1268 1269 /** 1270 * @brief set SSL context extra data 1271 * 1272 * @param ctx - SSL context point 1273 * @param idx - data index 1274 * @param arg - data point 1275 * 1276 * @return result 1277 * 1 : OK 1278 * 0 : failed 1279 */ 1280 int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, char *arg); 1281 1282 /** 1283 * @brief clear the SSL context option bit of "op" 1284 * 1285 * @param ctx - SSL context point 1286 * @param op - option 1287 * 1288 * @return SSL context option 1289 */ 1290 unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op); 1291 1292 /** 1293 * @brief get the SSL context option 1294 * 1295 * @param ctx - SSL context point 1296 * @param op - option 1297 * 1298 * @return SSL context option 1299 */ 1300 unsigned long SSL_CTX_get_options(SSL_CTX *ctx); 1301 1302 /** 1303 * @brief set the SSL context quiet shutdown mode 1304 * 1305 * @param ctx - SSL context point 1306 * @param mode - mode 1307 * 1308 * @return none 1309 */ 1310 void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); 1311 1312 /** 1313 * @brief get the SSL context X509 certification 1314 * 1315 * @param ctx - SSL context point 1316 * 1317 * @return X509 certification 1318 */ 1319 X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); 1320 1321 /** 1322 * @brief get the SSL context private key 1323 * 1324 * @param ctx - SSL context point 1325 * 1326 * @return private key 1327 */ 1328 EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); 1329 1330 /** 1331 * @brief set SSL context PSK identity hint 1332 * 1333 * @param ctx - SSL context point 1334 * @param hint - PSK identity hint 1335 * 1336 * @return result 1337 * 1 : OK 1338 * 0 : failed 1339 */ 1340 int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *hint); 1341 1342 /** 1343 * @brief set SSL context PSK server callback function 1344 * 1345 * @param ctx - SSL context point 1346 * @param callback - callback function 1347 * 1348 * @return none 1349 */ 1350 void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, 1351 unsigned int (*callback)(SSL *ssl, 1352 const char *identity, 1353 unsigned char *psk, 1354 int max_psk_len)); 1355 /** 1356 * @brief get alert description string 1357 * 1358 * @param value - alert value 1359 * 1360 * @return alert description string 1361 */ 1362 const char *SSL_alert_desc_string(int value); 1363 1364 /** 1365 * @brief get alert description long string 1366 * 1367 * @param value - alert value 1368 * 1369 * @return alert description long string 1370 */ 1371 const char *SSL_alert_desc_string_long(int value); 1372 1373 /** 1374 * @brief get alert type string 1375 * 1376 * @param value - alert value 1377 * 1378 * @return alert type string 1379 */ 1380 const char *SSL_alert_type_string(int value); 1381 1382 /** 1383 * @brief get alert type long string 1384 * 1385 * @param value - alert value 1386 * 1387 * @return alert type long string 1388 */ 1389 const char *SSL_alert_type_string_long(int value); 1390 1391 /** 1392 * @brief get SSL context of the SSL 1393 * 1394 * @param ssl - SSL point 1395 * 1396 * @return SSL context 1397 */ 1398 SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); 1399 1400 /** 1401 * @brief get SSL application data 1402 * 1403 * @param ssl - SSL point 1404 * 1405 * @return application data 1406 */ 1407 char *SSL_get_app_data(SSL *ssl); 1408 1409 /** 1410 * @brief get SSL cipher bits 1411 * 1412 * @param ssl - SSL point 1413 * @param alg_bits - algorithm bits 1414 * 1415 * @return strength bits 1416 */ 1417 int SSL_get_cipher_bits(const SSL *ssl, int *alg_bits); 1418 1419 /** 1420 * @brief get SSL cipher name 1421 * 1422 * @param ssl - SSL point 1423 * 1424 * @return SSL cipher name 1425 */ 1426 char *SSL_get_cipher_name(const SSL *ssl); 1427 1428 /** 1429 * @brief get SSL cipher version 1430 * 1431 * @param ssl - SSL point 1432 * 1433 * @return SSL cipher version 1434 */ 1435 char *SSL_get_cipher_version(const SSL *ssl); 1436 1437 /** 1438 * @brief get SSL extra data 1439 * 1440 * @param ssl - SSL point 1441 * @param idx - data index 1442 * 1443 * @return extra data 1444 */ 1445 char *SSL_get_ex_data(const SSL *ssl, int idx); 1446 1447 /** 1448 * @brief get index of the SSL extra data X509 storage context 1449 * 1450 * @param none 1451 * 1452 * @return data index 1453 */ 1454 int SSL_get_ex_data_X509_STORE_CTX_idx(void); 1455 1456 /** 1457 * @brief get peer certification chain 1458 * 1459 * @param ssl - SSL point 1460 * 1461 * @return certification chain 1462 */ 1463 STACK *SSL_get_peer_cert_chain(const SSL *ssl); 1464 1465 /** 1466 * @brief get peer certification 1467 * 1468 * @param ssl - SSL point 1469 * 1470 * @return certification 1471 */ 1472 X509 *SSL_get_peer_certificate(const SSL *ssl); 1473 1474 /** 1475 * @brief get SSL quiet shutdown mode 1476 * 1477 * @param ssl - SSL point 1478 * 1479 * @return quiet shutdown mode 1480 */ 1481 int SSL_get_quiet_shutdown(const SSL *ssl); 1482 1483 /** 1484 * @brief get SSL read only IO handle 1485 * 1486 * @param ssl - SSL point 1487 * 1488 * @return IO handle 1489 */ 1490 BIO *SSL_get_rbio(const SSL *ssl); 1491 1492 /** 1493 * @brief get SSL shared ciphers 1494 * 1495 * @param ssl - SSL point 1496 * @param buf - buffer to store the ciphers 1497 * @param len - buffer len 1498 * 1499 * @return shared ciphers 1500 */ 1501 char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len); 1502 1503 /** 1504 * @brief get SSL shutdown mode 1505 * 1506 * @param ssl - SSL point 1507 * 1508 * @return shutdown mode 1509 */ 1510 int SSL_get_shutdown(const SSL *ssl); 1511 1512 /** 1513 * @brief get SSL session time 1514 * 1515 * @param ssl - SSL point 1516 * 1517 * @return session time 1518 */ 1519 long SSL_get_time(const SSL *ssl); 1520 1521 /** 1522 * @brief get SSL session timeout time 1523 * 1524 * @param ssl - SSL point 1525 * 1526 * @return session timeout time 1527 */ 1528 long SSL_get_timeout(const SSL *ssl); 1529 1530 /** 1531 * @brief get SSL verifying mode 1532 * 1533 * @param ssl - SSL point 1534 * 1535 * @return verifying mode 1536 */ 1537 int SSL_get_verify_mode(const SSL *ssl); 1538 1539 /** 1540 * @brief get SSL verify parameters 1541 * 1542 * @param ssl - SSL point 1543 * 1544 * @return verify parameters 1545 */ 1546 X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); 1547 1548 /** 1549 * @brief set expected hostname the peer cert CN should have 1550 * 1551 * @param param - verify parameters from SSL_get0_param() 1552 * 1553 * @param name - the expected hostname 1554 * 1555 * @param namelen - the length of the hostname, or 0 if NUL terminated 1556 * 1557 * @return verify parameters 1558 */ 1559 int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, 1560 const char *name, size_t namelen); 1561 1562 /** 1563 * @brief set parameters for X509 host verify action 1564 * 1565 * @param param -verify parameters from SSL_get0_param() 1566 * 1567 * @param flags - bitfield of X509_CHECK_FLAG_... parameters to set 1568 * 1569 * @return 1 for success, 0 for failure 1570 */ 1571 int X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, 1572 unsigned long flags); 1573 1574 /** 1575 * @brief clear parameters for X509 host verify action 1576 * 1577 * @param param -verify parameters from SSL_get0_param() 1578 * 1579 * @param flags - bitfield of X509_CHECK_FLAG_... parameters to clear 1580 * 1581 * @return 1 for success, 0 for failure 1582 */ 1583 int X509_VERIFY_PARAM_clear_hostflags(X509_VERIFY_PARAM *param, 1584 unsigned long flags); 1585 1586 /** 1587 * @brief get SSL write only IO handle 1588 * 1589 * @param ssl - SSL point 1590 * 1591 * @return IO handle 1592 */ 1593 BIO *SSL_get_wbio(const SSL *ssl); 1594 1595 /** 1596 * @brief load SSL client CA certification file 1597 * 1598 * @param file - file name 1599 * 1600 * @return certification loading object 1601 */ 1602 STACK *SSL_load_client_CA_file(const char *file); 1603 1604 /** 1605 * @brief add SSL reference by '1' 1606 * 1607 * @param ssl - SSL point 1608 * 1609 * @return result 1610 * 1 : OK 1611 * 0 : failed 1612 */ 1613 int SSL_up_ref(SSL *ssl); 1614 1615 /** 1616 * @brief read and put data into buf, but not clear the SSL low-level storage 1617 * 1618 * @param ssl - SSL point 1619 * @param buf - storage buffer point 1620 * @param num - data bytes 1621 * 1622 * @return result 1623 * > 0 : OK, and return read bytes 1624 * = 0 : connect is closed 1625 * < 0 : a error catch 1626 */ 1627 int SSL_peek(SSL *ssl, void *buf, int num); 1628 1629 /** 1630 * @brief make SSL renegotiate 1631 * 1632 * @param ssl - SSL point 1633 * 1634 * @return result 1635 * 1 : OK 1636 * 0 : failed 1637 */ 1638 int SSL_renegotiate(SSL *ssl); 1639 1640 /** 1641 * @brief get the state string where SSL is reading 1642 * 1643 * @param ssl - SSL point 1644 * 1645 * @return state string 1646 */ 1647 const char *SSL_rstate_string(SSL *ssl); 1648 1649 /** 1650 * @brief get the statement long string where SSL is reading 1651 * 1652 * @param ssl - SSL point 1653 * 1654 * @return statement long string 1655 */ 1656 const char *SSL_rstate_string_long(SSL *ssl); 1657 1658 /** 1659 * @brief set SSL accept statement 1660 * 1661 * @param ssl - SSL point 1662 * 1663 * @return none 1664 */ 1665 void SSL_set_accept_state(SSL *ssl); 1666 1667 /** 1668 * @brief set SSL application data 1669 * 1670 * @param ssl - SSL point 1671 * @param arg - SSL application data point 1672 * 1673 * @return none 1674 */ 1675 void SSL_set_app_data(SSL *ssl, char *arg); 1676 1677 /** 1678 * @brief set SSL BIO 1679 * 1680 * @param ssl - SSL point 1681 * @param rbio - read only IO 1682 * @param wbio - write only IO 1683 * 1684 * @return none 1685 */ 1686 void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); 1687 1688 /** 1689 * @brief clear SSL option 1690 * 1691 * @param ssl - SSL point 1692 * @param op - clear option 1693 * 1694 * @return SSL option 1695 */ 1696 unsigned long SSL_clear_options(SSL *ssl, unsigned long op); 1697 1698 /** 1699 * @brief get SSL option 1700 * 1701 * @param ssl - SSL point 1702 * 1703 * @return SSL option 1704 */ 1705 unsigned long SSL_get_options(SSL *ssl); 1706 1707 /** 1708 * @brief clear SSL option 1709 * 1710 * @param ssl - SSL point 1711 * @param op - setting option 1712 * 1713 * @return SSL option 1714 */ 1715 unsigned long SSL_set_options(SSL *ssl, unsigned long op); 1716 1717 /** 1718 * @brief set SSL quiet shutdown mode 1719 * 1720 * @param ssl - SSL point 1721 * @param mode - quiet shutdown mode 1722 * 1723 * @return none 1724 */ 1725 void SSL_set_quiet_shutdown(SSL *ssl, int mode); 1726 1727 /** 1728 * @brief set SSL shutdown mode 1729 * 1730 * @param ssl - SSL point 1731 * @param mode - shutdown mode 1732 * 1733 * @return none 1734 */ 1735 void SSL_set_shutdown(SSL *ssl, int mode); 1736 1737 /** 1738 * @brief set SSL session time 1739 * 1740 * @param ssl - SSL point 1741 * @param t - session time 1742 * 1743 * @return session time 1744 */ 1745 long SSL_set_time(SSL *ssl, long t); 1746 1747 /** 1748 * @brief set SSL session timeout time 1749 * 1750 * @param ssl - SSL point 1751 * @param t - session timeout time 1752 * 1753 * @return session timeout time 1754 */ 1755 long SSL_set_timeout(SSL *ssl, long t); 1756 1757 /** 1758 * @brief get SSL statement string 1759 * 1760 * @param ssl - SSL point 1761 * 1762 * @return SSL statement string 1763 */ 1764 char *SSL_state_string(const SSL *ssl); 1765 1766 /** 1767 * @brief get SSL statement long string 1768 * 1769 * @param ssl - SSL point 1770 * 1771 * @return SSL statement long string 1772 */ 1773 char *SSL_state_string_long(const SSL *ssl); 1774 1775 /** 1776 * @brief get SSL renegotiation count 1777 * 1778 * @param ssl - SSL point 1779 * 1780 * @return renegotiation count 1781 */ 1782 long SSL_total_renegotiations(SSL *ssl); 1783 1784 /** 1785 * @brief get SSL version 1786 * 1787 * @param ssl - SSL point 1788 * 1789 * @return SSL version 1790 */ 1791 int SSL_version(const SSL *ssl); 1792 1793 /** 1794 * @brief set SSL PSK identity hint 1795 * 1796 * @param ssl - SSL point 1797 * @param hint - identity hint 1798 * 1799 * @return result 1800 * 1 : OK 1801 * 0 : failed 1802 */ 1803 int SSL_use_psk_identity_hint(SSL *ssl, const char *hint); 1804 1805 /** 1806 * @brief get SSL PSK identity hint 1807 * 1808 * @param ssl - SSL point 1809 * 1810 * @return identity hint 1811 */ 1812 const char *SSL_get_psk_identity_hint(SSL *ssl); 1813 1814 /** 1815 * @brief get SSL PSK identity 1816 * 1817 * @param ssl - SSL point 1818 * 1819 * @return identity 1820 */ 1821 const char *SSL_get_psk_identity(SSL *ssl); 1822 1823 #ifdef __cplusplus 1824 } 1825 #endif 1826 1827 #endif 1828