123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)moduleEvents=Signer_eventsopenClient_keysopenSigner_messageslettcp_scheme="tcp"letunix_scheme="unix"moduleMake(P:sigvalauthenticate:Tezos_crypto.Signature.Public_key_hash.tlist->Bytes.t->Tezos_crypto.Signature.ttzresultLwt.tend)=structopenPtyperequest_type=|Sign_request|Deterministic_nonce_request|Deterministic_nonce_hash_requestletbuild_requestpkhdatasignature=function|Sign_request->Request.Sign{Sign.Request.pkh;data;signature}|Deterministic_nonce_request->Request.Deterministic_nonce{Deterministic_nonce.Request.pkh;data;signature}|Deterministic_nonce_hash_request->Request.Deterministic_nonce_hash{Deterministic_nonce_hash.Request.pkh;data;signature}letmaybe_authenticatepkhmsgconn=letopenLwt_result_syntaxinlet*()=Tezos_base_unix.Socket.sendconnRequest.encodingRequest.Authorized_keysinlet*authorized_keys=Tezos_base_unix.Socket.recvconn(result_encodingAuthorized_keys.Response.encoding)inlet*v=Lwt.returnauthorized_keysinmatchvwith|No_authentication->return_none|Authorized_keysauthorized_keys->let*signature=authenticateauthorized_keys(Sign.Request.to_sign~pkh~data:msg)inreturn_somesignatureletwith_signer_operationpathpkhmsgrequest_typeenc=letopenLwt_result_syntaxinletf()=Tezos_base_unix.Socket.with_connectionpath(funconn->let*signature=maybe_authenticatepkhmsgconninletreq=build_requestpkhmsgsignaturerequest_typeinlet*()=Tezos_base_unix.Socket.sendconnRequest.encodingreqinTezos_base_unix.Socket.recvconn(result_encodingenc))inletrecloopn=let*!r=protect(fun()->f())inmatchrwith|ErrortraceasewhenList.exists(functionExnLwt_unix.Timeout->true|_->false)trace->ifn=0thenLwt.returneelselet*!()=Events.(emitSocket.signer_timeout)(predn)inloop(predn)|Error_ase->Lwt.returne|Okv->Lwt.returnvinloop3letsign?watermarkpathpkhmsg=letmsg=matchwatermarkwith|None->msg|Somewatermark->Bytes.cat(Tezos_crypto.Signature.bytes_of_watermarkwatermark)msginwith_signer_operationpathpkhmsgSign_requestSign.Response.encodingletdeterministic_noncepathpkhmsg=with_signer_operationpathpkhmsgDeterministic_nonce_requestDeterministic_nonce.Response.encodingletdeterministic_nonce_hashpathpkhmsg=with_signer_operationpathpkhmsgDeterministic_nonce_hash_requestDeterministic_nonce_hash.Response.encodingletsupports_deterministic_noncespathpkh=letopenLwt_result_syntaxinTezos_base_unix.Socket.with_connectionpath(funconn->let*()=Tezos_base_unix.Socket.sendconnRequest.encoding(Request.Supports_deterministic_noncespkh)inlet*supported=Tezos_base_unix.Socket.recvconn(result_encodingSupports_deterministic_nonces.Response.encoding)inLwt.returnsupported)letpublic_keypathpkh=letopenLwt_result_syntaxinTezos_base_unix.Socket.with_connectionpath(funconn->let*()=Tezos_base_unix.Socket.sendconnRequest.encoding(Request.Public_keypkh)inletencoding=result_encodingPublic_key.Response.encodinginlet*pk=Tezos_base_unix.Socket.recvconnencodinginLwt.returnpk)moduleUnix=structletscheme=unix_schemelettitle="Built-in tezos-signer using remote signer through hardcoded unix socket."letdescription="Valid locators are of the form\n - unix:/path/to/socket?pkh=tz1..."includeClient_keys.Signature_typeletparseuri=letopenResult_syntaxinassert(Uri.schemeuri=Somescheme);matchUri.get_query_paramuri"pkh"with|None->error_with"Missing the query parameter: 'pkh=tz1...'"|Somekey->let+key=Tezos_crypto.Signature.Public_key_hash.of_b58checkkeyin(Tezos_base_unix.Socket.Unix(Uri.pathuri),key)letparseuri=parseuri|>record_trace(Invalid_uriuri)|>Lwt.returnletpublic_keyuri=letopenLwt_result_syntaxinlet*path,pkh=parse(uri:pk_uri:>Uri.t)inpublic_keypathpkhletneuterizeuri=letopenLwt_result_syntaxinlet*?v=Client_keys.make_pk_uri(uri:sk_uri:>Uri.t)inreturnvletpublic_key_hashuri=letopenLwt_result_syntaxinlet*pk=public_keyuriinreturn(Tezos_crypto.Signature.Public_key.hashpk,Somepk)letimport_secret_key~io:_=public_key_hashletsign?watermarkurimsg=letopenLwt_result_syntaxinlet*path,pkh=parse(uri:sk_uri:>Uri.t)insign?watermarkpathpkhmsgletdeterministic_nonceurimsg=letopenLwt_result_syntaxinlet*path,pkh=parse(uri:sk_uri:>Uri.t)indeterministic_noncepathpkhmsgletdeterministic_nonce_hashurimsg=letopenLwt_result_syntaxinlet*path,pkh=parse(uri:sk_uri:>Uri.t)indeterministic_nonce_hashpathpkhmsgletsupports_deterministic_noncesuri=letopenLwt_result_syntaxinlet*path,pkh=parse(uri:sk_uri:>Uri.t)insupports_deterministic_noncespathpkhendmoduleTcp=structletscheme=tcp_schemelettitle="Built-in tezos-signer using remote signer through hardcoded tcp socket."letdescription="Valid locators are of the form\n - tcp://host:port/tz1..."includeClient_keys.Signature_typeletparseuri=letopenResult_syntaxinassert(Uri.schemeuri=Somescheme);match(Uri.hosturi,Uri.porturi)with|None,_->error_with"Missing host address"|_,None->error_with"Missing host port"|Somepath,Someport->letpkh=Uri.pathuriinletpkh=tryString.(subpkh1(lengthpkh-1))with_->""inlet+pkh=Tezos_crypto.Signature.Public_key_hash.of_b58checkpkhinlettcp_socket=Tezos_base_unix.Socket.Tcp(path,string_of_intport,[Lwt_unix.AI_SOCKTYPESOCK_STREAM])in(tcp_socket,pkh)letparseuri=parseuri|>record_trace(Invalid_uriuri)|>Lwt.returnletpublic_keyuri=letopenLwt_result_syntaxinlet*path,pkh=parse(uri:pk_uri:>Uri.t)inpublic_keypathpkhletneuterizeuri=letopenLwt_result_syntaxinlet*?v=Client_keys.make_pk_uri(uri:sk_uri:>Uri.t)inreturnvletpublic_key_hashuri=letopenLwt_result_syntaxinlet*pk=public_keyuriinreturn(Tezos_crypto.Signature.Public_key.hashpk,Somepk)letimport_secret_key~io:_=public_key_hashletsign?watermarkurimsg=letopenLwt_result_syntaxinlet*path,pkh=parse(uri:sk_uri:>Uri.t)insign?watermarkpathpkhmsgletdeterministic_nonceurimsg=letopenLwt_result_syntaxinlet*path,pkh=parse(uri:sk_uri:>Uri.t)indeterministic_noncepathpkhmsgletdeterministic_nonce_hashurimsg=letopenLwt_result_syntaxinlet*path,pkh=parse(uri:sk_uri:>Uri.t)indeterministic_nonce_hashpathpkhmsgletsupports_deterministic_noncesuri=letopenLwt_result_syntaxinlet*path,pkh=parse(uri:sk_uri:>Uri.t)insupports_deterministic_noncespathpkhendendletmake_unix_basepath=Uri.make~scheme:unix_scheme~path()letmake_tcp_basehostport=Uri.make~scheme:tcp_scheme~host~port()