123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311(*
Copyright (C) 2003-2005 Samuel Mimram
This file is part of Ocaml-ssl.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*)(* $Id$ *)typeprotocol=|SSLv23|SSLv3|TLSv1|TLSv1_1|TLSv1_2typecontexttypecertificatetypesockettypessl_error=|Error_none|Error_ssl|Error_want_read|Error_want_write|Error_want_x509_lookup|Error_syscall|Error_zero_return|Error_want_connect|Error_want_accepttypeverify_error=|Error_v_unable_to_get_issuer_cert|Error_v_unable_to_get_ctl|Error_v_unable_to_decrypt_cert_signature|Error_v_unable_to_decrypt_CRL_signature|Error_v_unable_to_decode_issuer_public_key|Error_v_cert_signature_failure|Error_v_CRL_signature_failure|Error_v_cert_not_yet_valid|Error_v_cert_has_expired|Error_v_CRL_not_yet_valid|Error_v_CRL_has_expired|Error_v_error_in_cert_not_before_field|Error_v_error_in_cert_not_after_field|Error_v_error_in_CRL_last_update_field|Error_v_error_in_CRL_next_update_field|Error_v_out_of_mem|Error_v_depth_zero_self_signed_cert|Error_v_self_signed_cert_in_chain|Error_v_unable_to_get_issuer_cert_locally|Error_v_unable_to_verify_leaf_signature|Error_v_cert_chain_too_long|Error_v_cert_revoked|Error_v_invalid_CA|Error_v_path_length_exceeded|Error_v_invalid_purpose|Error_v_cert_untrusted|Error_v_cert_rejected|Error_v_subject_issuer_mismatch|Error_v_akid_skid_mismatch|Error_v_akid_issuer_serial_mismatch|Error_v_keyusage_no_certsign|Error_v_application_verificationtypebigarray=(char,Bigarray.int8_unsigned_elt,Bigarray.c_layout)Bigarray.Array1.texternalget_error_string:unit->string="ocaml_ssl_get_error_string"exceptionMethod_errorexceptionContext_errorexceptionCertificate_errorexceptionCipher_errorexceptionDiffie_hellman_errorexceptionEc_curve_errorexceptionPrivate_key_errorexceptionUnmatching_keysexceptionInvalid_socketexceptionHandler_errorexceptionConnection_errorofssl_errorexceptionAccept_errorofssl_errorexceptionRead_errorofssl_errorexceptionWrite_errorofssl_errorexceptionVerify_errorofverify_errorlet()=Printexc.register_printer(function|Method_error->Some("SSL: Method error")|Context_error->Some("SSL: Context error")|Certificate_error->Some("SSL: Certificate error")|Cipher_error->Some("SSL: Cihper error")|Diffie_hellman_error->Some("SSL: Diffie Hellman error")|Ec_curve_error->Some("SSL: EC curve error")|Private_key_error->Some("SSL: Privte key error")|Unmatching_keys->Some("SSL: Unmatching keys")|Invalid_socket->Some("SSL: Invalid socket")|Handler_error->Some("SSL: Handler error")|Connection_error_->Some("SSL connection() error: "^(get_error_string()))|Accept_error_->Some("SSL accept() error: "^(get_error_string()))|Read_error_->Some("SSL read() error: "^(get_error_string()))|Write_error_->Some("SSL write() error: "^(get_error_string()))|Verify_error_->Some("SSL verify() error: "^(get_error_string()))|_->None)let()=Callback.register_exception"ssl_exn_method_error"Method_error;Callback.register_exception"ssl_exn_context_error"Context_error;Callback.register_exception"ssl_exn_certificate_error"Certificate_error;Callback.register_exception"ssl_exn_cipher_error"Cipher_error;Callback.register_exception"ssl_exn_diffie_hellman_error"Diffie_hellman_error;Callback.register_exception"ssl_exn_ec_curve_error"Ec_curve_error;Callback.register_exception"ssl_exn_private_key_error"Private_key_error;Callback.register_exception"ssl_exn_unmatching_keys"Unmatching_keys;Callback.register_exception"ssl_exn_invalid_socket"Invalid_socket;Callback.register_exception"ssl_exn_handler_error"Handler_error;Callback.register_exception"ssl_exn_connection_error"(Connection_errorError_none);Callback.register_exception"ssl_exn_accept_error"(Accept_errorError_none);Callback.register_exception"ssl_exn_read_error"(Read_errorError_none);Callback.register_exception"ssl_exn_write_error"(Write_errorError_none);Callback.register_exception"ssl_exn_verify_error"(Verify_errorError_v_application_verification)letthread_safe=reffalseexternalinit:bool->unit="ocaml_ssl_init"letts=thread_safeletinit?thread_safe()=letthread_safe=matchthread_safewith|Someb->b|None->!tsininitthread_safetypecontext_type=|Client_context|Server_context|Both_contextexternalcreate_context:protocol->context_type->context="ocaml_ssl_create_context"externaluse_certificate:context->string->string->unit="ocaml_ssl_ctx_use_certificate"externalset_password_callback:context->(bool->string)->unit="ocaml_ssl_ctx_set_default_passwd_cb"externalembed_socket:Unix.file_descr->context->socket="ocaml_ssl_embed_socket"externaldisable_protocols:context->protocollist->unit="ocaml_ssl_disable_protocols"externalset_cipher_list:context->string->unit="ocaml_ssl_ctx_set_cipher_list"externalhonor_cipher_order:context->unit="ocaml_ssl_ctx_honor_cipher_order"externalinit_dh_from_file:context->string->unit="ocaml_ssl_ctx_init_dh_from_file"externalinit_ec_from_named_curve:context->string->unit="ocaml_ssl_ctx_init_ec_from_named_curve"externalload_verify_locations:context->string->string->unit="ocaml_ssl_ctx_load_verify_locations"externalget_verify_result:socket->int="ocaml_ssl_get_verify_result"typeverify_mode=|Verify_peer|Verify_fail_if_no_peer_cert|Verify_client_oncetypeverify_callbackexternalget_client_verify_callback_ptr:unit->verify_callback="ocaml_ssl_get_client_verify_callback_ptr"letclient_verify_callback=get_client_verify_callback_ptr()externalset_client_verify_callback_verbose:bool->unit="ocaml_ssl_set_client_verify_callback_verbose"externalset_verify:context->verify_modelist->verify_callbackoption->unit="ocaml_ssl_ctx_set_verify"externalset_verify_depth:context->int->unit="ocaml_ssl_ctx_set_verify_depth"externalset_client_CA_list_from_file:context->string->unit="ocaml_ssl_ctx_set_client_CA_list_from_file"typecipherexternalget_cipher:socket->cipher="ocaml_ssl_get_current_cipher"externalget_cipher_description:cipher->string="ocaml_ssl_get_cipher_description"(* TODO: get_cipher_bits *)externalget_cipher_name:cipher->string="ocaml_ssl_get_cipher_name"externalget_cipher_version:cipher->string="ocaml_ssl_get_cipher_version"externalget_certificate:socket->certificate="ocaml_ssl_get_certificate"externalread_certificate:string->certificate="ocaml_ssl_read_certificate"externalwrite_certificate:string->certificate->unit="ocaml_ssl_write_certificate"externalget_issuer:certificate->string="ocaml_ssl_get_issuer"externalget_subject:certificate->string="ocaml_ssl_get_subject"externalfile_descr_of_socket:socket->Unix.file_descr="ocaml_ssl_get_file_descr"externalset_client_SNI_hostname:socket->string->unit="ocaml_ssl_set_client_SNI_hostname"externalconnect:socket->unit="ocaml_ssl_connect"externalverify:socket->unit="ocaml_ssl_verify"externalwrite:socket->Bytes.t->int->int->int="ocaml_ssl_write"externalwrite_substring:socket->string->int->int->int="ocaml_ssl_write"externalwrite_bigarray:socket->bigarray->int->int->int="ocaml_ssl_write_bigarray"externalwrite_bigarray_blocking:socket->bigarray->int->int->int="ocaml_ssl_write_bigarray_blocking"externalread:socket->Bytes.t->int->int->int="ocaml_ssl_read"externalread_into_bigarray:socket->bigarray->int->int->int="ocaml_ssl_read_into_bigarray"externalread_into_bigarray_blocking:socket->bigarray->int->int->int="ocaml_ssl_read_into_bigarray_blocking"externalaccept:socket->unit="ocaml_ssl_accept"externalflush:socket->unit="ocaml_ssl_flush"externalshutdown:socket->unit="ocaml_ssl_shutdown"letopen_connection_with_contextcontextsockaddr=letdomain=matchsockaddrwith|Unix.ADDR_UNIX_->Unix.PF_UNIX|Unix.ADDR_INET(_,_)->Unix.PF_INETinletsock=Unix.socketdomainUnix.SOCK_STREAM0intryUnix.connectsocksockaddr;letssl=embed_socketsockcontextinconnectssl;sslwith|exn->Unix.closesock;raiseexnletopen_connectionssl_methodsockaddr=open_connection_with_context(create_contextssl_methodClient_context)sockaddrletshutdown_connection=shutdownletoutput_stringssls=ignore(write_substringssls0(String.lengths))letoutput_charsslc=lettmp=String.make1cinignore(write_substringssltmp01)letoutput_intssli=lettmp=Bytes.create4inBytes.settmp0(char_of_int(ilsr24));Bytes.settmp1(char_of_int((ilsr16)land0xff));Bytes.settmp2(char_of_int((ilsr8)land0xff));Bytes.settmp3(char_of_int(iland0xff));ifwritessltmp04<>4thenfailwith"output_int error: all the byte were not sent"letinput_stringssl=letbufsize=1024inletbuf=Bytes.createbufsizeinletret=ref""inletr=ref1inwhile!r<>0dor:=readsslbuf0bufsize;ret:=!ret^(Bytes.sub_stringbuf0!r)done;!retletinput_charssl=lettmp=Bytes.create1inifreadssltmp01<>1thenraiseEnd_of_fileelseBytes.gettmp0letinput_intssl=leti=ref0inlettmp=Bytes.create4inignore(readssltmp04);i:=int_of_char(Bytes.gettmp0);i:=(!ilsl8)+int_of_char(Bytes.gettmp1);i:=(!ilsl8)+int_of_char(Bytes.gettmp2);i:=(!ilsl8)+int_of_char(Bytes.gettmp3);!i