github.com/decred/dcrlnd@v0.7.6/lnrpc/signrpc/signer_server.go (about)

     1  //go:build !no_signrpc
     2  // +build !no_signrpc
     3  
     4  package signrpc
     5  
     6  import (
     7  	"bytes"
     8  	"context"
     9  	"fmt"
    10  	"io/ioutil"
    11  	"os"
    12  	"path/filepath"
    13  
    14  	"github.com/decred/dcrd/chaincfg/chainhash"
    15  	"github.com/decred/dcrd/dcrec/secp256k1/v4"
    16  	"github.com/decred/dcrd/txscript/v4"
    17  	"github.com/decred/dcrd/wire"
    18  	"github.com/decred/dcrlnd/input"
    19  	"github.com/decred/dcrlnd/keychain"
    20  	"github.com/decred/dcrlnd/lnrpc"
    21  	"github.com/decred/dcrlnd/lnwire"
    22  	"github.com/decred/dcrlnd/macaroons"
    23  	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
    24  	"google.golang.org/grpc"
    25  	"gopkg.in/macaroon-bakery.v2/bakery"
    26  )
    27  
    28  const (
    29  	// subServerName is the name of the sub rpc server. We'll use this name
    30  	// to register ourselves, and we also require that the main
    31  	// SubServerConfigDispatcher instance recognize this as the name of the
    32  	// config file that we need.
    33  	subServerName = "SignRPC"
    34  )
    35  
    36  var (
    37  	// macaroonOps are the set of capabilities that our minted macaroon (if
    38  	// it doesn't already exist) will have.
    39  	macaroonOps = []bakery.Op{
    40  		{
    41  			Entity: "signer",
    42  			Action: "generate",
    43  		},
    44  		{
    45  			Entity: "signer",
    46  			Action: "read",
    47  		},
    48  	}
    49  
    50  	// macPermissions maps RPC calls to the permissions they require.
    51  	macPermissions = map[string][]bakery.Op{
    52  		"/signrpc.Signer/SignOutputRaw": {{
    53  			Entity: "signer",
    54  			Action: "generate",
    55  		}},
    56  		"/signrpc.Signer/ComputeInputScript": {{
    57  			Entity: "signer",
    58  			Action: "generate",
    59  		}},
    60  		"/signrpc.Signer/SignMessage": {{
    61  			Entity: "signer",
    62  			Action: "generate",
    63  		}},
    64  		"/signrpc.Signer/VerifyMessage": {{
    65  			Entity: "signer",
    66  			Action: "read",
    67  		}},
    68  		"/signrpc.Signer/DeriveSharedKey": {{
    69  			Entity: "signer",
    70  			Action: "generate",
    71  		}},
    72  	}
    73  
    74  	// DefaultSignerMacFilename is the default name of the signer macaroon
    75  	// that we expect to find via a file handle within the main
    76  	// configuration file in this package.
    77  	DefaultSignerMacFilename = "signer.macaroon"
    78  )
    79  
    80  // ServerShell is a shell struct holding a reference to the actual sub-server.
    81  // It is used to register the gRPC sub-server with the root server before we
    82  // have the necessary dependencies to populate the actual sub-server.
    83  type ServerShell struct {
    84  	SignerServer
    85  }
    86  
    87  // Server is a sub-server of the main RPC server: the signer RPC. This sub RPC
    88  // server allows external callers to access the full signing capabilities of
    89  // lnd. This allows callers to create custom protocols, external to lnd, even
    90  // backed by multiple distinct lnd across independent failure domains.
    91  type Server struct {
    92  	cfg *Config
    93  }
    94  
    95  // A compile time check to ensure that Server fully implements the SignerServer
    96  // gRPC service.
    97  var _ SignerServer = (*Server)(nil)
    98  
    99  // New returns a new instance of the signrpc Signer sub-server. We also return
   100  // the set of permissions for the macaroons that we may create within this
   101  // method. If the macaroons we need aren't found in the filepath, then we'll
   102  // create them on start up. If we're unable to locate, or create the macaroons
   103  // we need, then we'll return with an error.
   104  func New(cfg *Config) (*Server, lnrpc.MacaroonPerms, error) {
   105  	// If the path of the signer macaroon wasn't generated, then we'll
   106  	// assume that it's found at the default network directory.
   107  	if cfg.SignerMacPath == "" {
   108  		cfg.SignerMacPath = filepath.Join(
   109  			cfg.NetworkDir, DefaultSignerMacFilename,
   110  		)
   111  	}
   112  
   113  	// Now that we know the full path of the signer macaroon, we can check
   114  	// to see if we need to create it or not. If stateless_init is set
   115  	// then we don't write the macaroons.
   116  	macFilePath := cfg.SignerMacPath
   117  	if cfg.MacService != nil && !cfg.MacService.StatelessInit &&
   118  		!lnrpc.FileExists(macFilePath) {
   119  
   120  		log.Infof("Making macaroons for Signer RPC Server at: %v",
   121  			macFilePath)
   122  
   123  		// At this point, we know that the signer macaroon doesn't yet,
   124  		// exist, so we need to create it with the help of the main
   125  		// macaroon service.
   126  		signerMac, err := cfg.MacService.NewMacaroon(
   127  			context.Background(), macaroons.DefaultRootKeyID,
   128  			macaroonOps...,
   129  		)
   130  		if err != nil {
   131  			return nil, nil, err
   132  		}
   133  		signerMacBytes, err := signerMac.M().MarshalBinary()
   134  		if err != nil {
   135  			return nil, nil, err
   136  		}
   137  		err = ioutil.WriteFile(macFilePath, signerMacBytes, 0644)
   138  		if err != nil {
   139  			_ = os.Remove(macFilePath)
   140  			return nil, nil, err
   141  		}
   142  	}
   143  
   144  	signerServer := &Server{
   145  		cfg: cfg,
   146  	}
   147  
   148  	return signerServer, macPermissions, nil
   149  }
   150  
   151  // Start launches any helper goroutines required for the rpcServer to function.
   152  //
   153  // NOTE: This is part of the lnrpc.SubServer interface.
   154  func (s *Server) Start() error {
   155  	return nil
   156  }
   157  
   158  // Stop signals any active goroutines for a graceful closure.
   159  //
   160  // NOTE: This is part of the lnrpc.SubServer interface.
   161  func (s *Server) Stop() error {
   162  	return nil
   163  }
   164  
   165  // Name returns a unique string representation of the sub-server. This can be
   166  // used to identify the sub-server and also de-duplicate them.
   167  //
   168  // NOTE: This is part of the lnrpc.SubServer interface.
   169  func (s *Server) Name() string {
   170  	return subServerName
   171  }
   172  
   173  // RegisterWithRootServer will be called by the root gRPC server to direct a
   174  // sub RPC server to register itself with the main gRPC root server. Until this
   175  // is called, each sub-server won't be able to have
   176  // requests routed towards it.
   177  //
   178  // NOTE: This is part of the lnrpc.GrpcHandler interface.
   179  func (r *ServerShell) RegisterWithRootServer(grpcServer *grpc.Server) error {
   180  	// We make sure that we register it with the main gRPC server to ensure
   181  	// all our methods are routed properly.
   182  	RegisterSignerServer(grpcServer, r)
   183  
   184  	log.Debugf("Signer RPC server successfully register with root gRPC " +
   185  		"server")
   186  
   187  	return nil
   188  }
   189  
   190  // RegisterWithRestServer will be called by the root REST mux to direct a sub
   191  // RPC server to register itself with the main REST mux server. Until this is
   192  // called, each sub-server won't be able to have requests routed towards it.
   193  //
   194  // NOTE: This is part of the lnrpc.GrpcHandler interface.
   195  func (r *ServerShell) RegisterWithRestServer(ctx context.Context,
   196  	mux *runtime.ServeMux, dest string, opts []grpc.DialOption) error {
   197  
   198  	// We make sure that we register it with the main REST server to ensure
   199  	// all our methods are routed properly.
   200  	err := RegisterSignerHandlerFromEndpoint(ctx, mux, dest, opts)
   201  	if err != nil {
   202  		log.Errorf("Could not register Signer REST server "+
   203  			"with root REST server: %v", err)
   204  		return err
   205  	}
   206  
   207  	log.Debugf("Signer REST server successfully registered with " +
   208  		"root REST server")
   209  	return nil
   210  }
   211  
   212  // CreateSubServer populates the subserver's dependencies using the passed
   213  // SubServerConfigDispatcher. This method should fully initialize the
   214  // sub-server instance, making it ready for action. It returns the macaroon
   215  // permissions that the sub-server wishes to pass on to the root server for all
   216  // methods routed towards it.
   217  //
   218  // NOTE: This is part of the lnrpc.GrpcHandler interface.
   219  func (r *ServerShell) CreateSubServer(configRegistry lnrpc.SubServerConfigDispatcher) (
   220  	lnrpc.SubServer, lnrpc.MacaroonPerms, error) {
   221  
   222  	subServer, macPermissions, err := createNewSubServer(configRegistry)
   223  	if err != nil {
   224  		return nil, nil, err
   225  	}
   226  
   227  	r.SignerServer = subServer
   228  	return subServer, macPermissions, nil
   229  }
   230  
   231  // SignOutputRaw generates a signature for the passed transaction according to
   232  // the data within the passed SignReq. If we're unable to find the keys that
   233  // correspond to the KeyLocators in the SignReq then we'll return an error.
   234  // Additionally, if the user doesn't provide the set of required parameters, or
   235  // provides an invalid transaction, then we'll return with an error.
   236  //
   237  // NOTE: The resulting signature should be void of a sighash byte.
   238  func (s *Server) SignOutputRaw(ctx context.Context, in *SignReq) (*SignResp,
   239  	error) {
   240  
   241  	switch {
   242  	// If the client doesn't specify a transaction, then there's nothing to
   243  	// sign, so we'll exit early.
   244  	case len(in.RawTxBytes) == 0:
   245  		return nil, fmt.Errorf("a transaction to sign MUST be " +
   246  			"passed in")
   247  
   248  	// If the client doesn't tell us *how* to sign the transaction, then we
   249  	// can't sign anything, so we'll exit early.
   250  	case len(in.SignDescs) == 0:
   251  		return nil, fmt.Errorf("at least one SignDescs MUST be " +
   252  			"passed in")
   253  	}
   254  
   255  	// Now that we know we have an actual transaction to decode, we'll
   256  	// deserialize it into something that we can properly utilize.
   257  	var (
   258  		txToSign wire.MsgTx
   259  		err      error
   260  	)
   261  	txReader := bytes.NewReader(in.RawTxBytes)
   262  	if err := txToSign.Deserialize(txReader); err != nil {
   263  		return nil, fmt.Errorf("unable to decode tx: %v", err)
   264  	}
   265  
   266  	log.Debugf("Generating sigs for %v inputs: ", len(in.SignDescs))
   267  
   268  	// With the transaction deserialized, we'll now convert sign descs so
   269  	// we can feed it into the actual signer.
   270  	signDescs := make([]*input.SignDescriptor, 0, len(in.SignDescs))
   271  	for _, signDesc := range in.SignDescs {
   272  		keyDesc := signDesc.KeyDesc
   273  
   274  		// The caller can either specify the key using the raw pubkey,
   275  		// or the description of the key. We'll still attempt to parse
   276  		// both if both were provided however, to ensure the underlying
   277  		// SignOutputRaw has as much information as possible.
   278  		var (
   279  			targetPubKey *secp256k1.PublicKey
   280  			keyLoc       keychain.KeyLocator
   281  		)
   282  
   283  		// If this method doesn't return nil, then we know that user is
   284  		// attempting to include a raw serialized pub key.
   285  		if keyDesc.GetRawKeyBytes() != nil {
   286  			targetPubKey, err = parseRawKeyBytes(
   287  				keyDesc.GetRawKeyBytes(),
   288  			)
   289  			if err != nil {
   290  				return nil, err
   291  			}
   292  		}
   293  
   294  		// Similarly, if they specified a key locator, then we'll parse
   295  		// that as well.
   296  		if keyDesc.GetKeyLoc() != nil {
   297  			protoLoc := keyDesc.GetKeyLoc()
   298  			keyLoc = keychain.KeyLocator{
   299  				Family: keychain.KeyFamily(
   300  					protoLoc.KeyFamily,
   301  				),
   302  				Index: uint32(protoLoc.KeyIndex),
   303  			}
   304  		}
   305  
   306  		// If a witness script isn't passed, then we can't proceed, as
   307  		// in the p2wsh case, we can't properly generate the sighash.
   308  		// A P2WKH doesn't need a witness script. But SignOutputRaw
   309  		// still needs to know the PK script that was used for the
   310  		// output. We'll send it in the WitnessScript field, the
   311  		// SignOutputRaw RPC will know what to do with it when creating
   312  		// the sighash.
   313  		if len(signDesc.WitnessScript) == 0 {
   314  			return nil, fmt.Errorf("witness script MUST be " +
   315  				"specified")
   316  		}
   317  
   318  		// If the users provided a double tweak, then we'll need to
   319  		// parse that out now to ensure their input is properly signed.
   320  		var tweakPrivKey *secp256k1.PrivateKey
   321  		if len(signDesc.DoubleTweak) != 0 {
   322  			tweakPrivKey = secp256k1.PrivKeyFromBytes(
   323  				signDesc.DoubleTweak,
   324  			)
   325  		}
   326  
   327  		// Finally, with verification and parsing complete, we can
   328  		// construct the final sign descriptor to generate the proper
   329  		// signature for this input.
   330  		signDescs = append(signDescs, &input.SignDescriptor{
   331  			KeyDesc: keychain.KeyDescriptor{
   332  				KeyLocator: keyLoc,
   333  				PubKey:     targetPubKey,
   334  			},
   335  			SingleTweak:   signDesc.SingleTweak,
   336  			DoubleTweak:   tweakPrivKey,
   337  			WitnessScript: signDesc.WitnessScript,
   338  			Output: &wire.TxOut{
   339  				Value:    signDesc.Output.Value,
   340  				PkScript: signDesc.Output.PkScript,
   341  			},
   342  			HashType:   txscript.SigHashType(signDesc.Sighash),
   343  			InputIndex: int(signDesc.InputIndex),
   344  		})
   345  	}
   346  
   347  	// Now that we've mapped all the proper sign descriptors, we can
   348  	// request signatures for each of them, passing in the transaction to
   349  	// be signed.
   350  	numSigs := len(in.SignDescs)
   351  	resp := &SignResp{
   352  		RawSigs: make([][]byte, numSigs),
   353  	}
   354  	for i, signDesc := range signDescs {
   355  		sig, err := s.cfg.Signer.SignOutputRaw(&txToSign, signDesc)
   356  		if err != nil {
   357  			log.Errorf("unable to generate sig for input "+
   358  				"#%v: %v", i, err)
   359  
   360  			return nil, err
   361  		}
   362  
   363  		resp.RawSigs[i] = sig.Serialize()
   364  	}
   365  
   366  	return resp, nil
   367  }
   368  
   369  // ComputeInputScript generates a complete InputIndex for the passed
   370  // transaction with the signature as defined within the passed SignDescriptor.
   371  // This method should be capable of generating the proper input script for both
   372  // regular p2wkh output and p2wkh outputs nested within a regular p2sh output.
   373  //
   374  // Note that when using this method to sign inputs belonging to the wallet, the
   375  // only items of the SignDescriptor that need to be populated are pkScript in
   376  // the TxOut field, the value in that same field, and finally the input index.
   377  func (s *Server) ComputeInputScript(ctx context.Context,
   378  	in *SignReq) (*InputScriptResp, error) {
   379  
   380  	switch {
   381  	// If the client doesn't specify a transaction, then there's nothing to
   382  	// sign, so we'll exit early.
   383  	case len(in.RawTxBytes) == 0:
   384  		return nil, fmt.Errorf("a transaction to sign MUST be " +
   385  			"passed in")
   386  
   387  	// If the client doesn't tell us *how* to sign the transaction, then we
   388  	// can't sign anything, so we'll exit early.
   389  	case len(in.SignDescs) == 0:
   390  		return nil, fmt.Errorf("at least one SignDescs MUST be " +
   391  			"passed in")
   392  	}
   393  
   394  	// Now that we know we have an actual transaction to decode, we'll
   395  	// deserialize it into something that we can properly utilize.
   396  	var txToSign wire.MsgTx
   397  	txReader := bytes.NewReader(in.RawTxBytes)
   398  	if err := txToSign.Deserialize(txReader); err != nil {
   399  		return nil, fmt.Errorf("unable to decode tx: %v", err)
   400  	}
   401  
   402  	signDescs := make([]*input.SignDescriptor, 0, len(in.SignDescs))
   403  	for _, signDesc := range in.SignDescs {
   404  		// For this method, the only fields that we care about are the
   405  		// hash type, and the information concerning the output as we
   406  		// only know how to provide full witnesses for outputs that we
   407  		// solely control.
   408  		signDescs = append(signDescs, &input.SignDescriptor{
   409  			Output: &wire.TxOut{
   410  				Value:    signDesc.Output.Value,
   411  				PkScript: signDesc.Output.PkScript,
   412  			},
   413  			HashType:   txscript.SigHashType(signDesc.Sighash),
   414  			InputIndex: int(signDesc.InputIndex),
   415  		})
   416  	}
   417  
   418  	// With all of our signDescs assembled, we can now generate a valid
   419  	// input script for each of them, and collate the responses to return
   420  	// back to the caller.
   421  	numWitnesses := len(in.SignDescs)
   422  	resp := &InputScriptResp{
   423  		InputScripts: make([]*InputScript, numWitnesses),
   424  	}
   425  	for i, signDesc := range signDescs {
   426  		inputScript, err := s.cfg.Signer.ComputeInputScript(
   427  			&txToSign, signDesc,
   428  		)
   429  		if err != nil {
   430  			return nil, err
   431  		}
   432  
   433  		resp.InputScripts[i] = &InputScript{
   434  			Witness:   inputScript.Witness,
   435  			SigScript: inputScript.SigScript,
   436  		}
   437  	}
   438  
   439  	return resp, nil
   440  }
   441  
   442  // SignMessage signs a message with the key specified in the key locator. The
   443  // returned signature is fixed-size LN wire format encoded.
   444  func (s *Server) SignMessage(_ context.Context,
   445  	in *SignMessageReq) (*SignMessageResp, error) {
   446  
   447  	if in.Msg == nil {
   448  		return nil, fmt.Errorf("a message to sign MUST be passed in")
   449  	}
   450  	if in.KeyLoc == nil {
   451  		return nil, fmt.Errorf("a key locator MUST be passed in")
   452  	}
   453  
   454  	// Describe the private key we'll be using for signing.
   455  	keyLocator := keychain.KeyLocator{
   456  		Family: keychain.KeyFamily(in.KeyLoc.KeyFamily),
   457  		Index:  uint32(in.KeyLoc.KeyIndex),
   458  	}
   459  
   460  	// To allow a watch-only wallet to forward the SignMessageCompact to an
   461  	// endpoint that doesn't add the message prefix, we allow this RPC to
   462  	// also return the compact signature format instead of adding a flag to
   463  	// the lnrpc.SignMessage call that removes the message prefix.
   464  	if in.CompactSig {
   465  		sigBytes, err := s.cfg.KeyRing.SignMessageCompact(
   466  			keyLocator, in.Msg, in.DoubleHash,
   467  		)
   468  		if err != nil {
   469  			return nil, fmt.Errorf("can't sign the hash: %v", err)
   470  		}
   471  
   472  		return &SignMessageResp{
   473  			Signature: sigBytes,
   474  		}, nil
   475  	}
   476  
   477  	// Create the raw ECDSA signature first and convert it to the final wire
   478  	// format after.
   479  	sig, err := s.cfg.KeyRing.SignMessage(
   480  		keyLocator, in.Msg, in.DoubleHash,
   481  	)
   482  	if err != nil {
   483  		return nil, fmt.Errorf("can't sign the hash: %v", err)
   484  	}
   485  	wireSig, err := lnwire.NewSigFromSignature(sig)
   486  	if err != nil {
   487  		return nil, fmt.Errorf("can't convert to wire format: %v", err)
   488  	}
   489  	return &SignMessageResp{
   490  		Signature: wireSig.ToSignatureBytes(),
   491  	}, nil
   492  }
   493  
   494  // VerifyMessage verifies a signature over a message using the public key
   495  // provided. The signature must be fixed-size LN wire format encoded.
   496  func (s *Server) VerifyMessage(ctx context.Context,
   497  	in *VerifyMessageReq) (*VerifyMessageResp, error) {
   498  
   499  	if in.Msg == nil {
   500  		return nil, fmt.Errorf("a message to verify MUST be passed in")
   501  	}
   502  	if in.Signature == nil {
   503  		return nil, fmt.Errorf("a signature to verify MUST be passed " +
   504  			"in")
   505  	}
   506  	if in.Pubkey == nil {
   507  		return nil, fmt.Errorf("a pubkey to verify MUST be passed in")
   508  	}
   509  	pubkey, err := secp256k1.ParsePubKey(in.Pubkey)
   510  	if err != nil {
   511  		return nil, fmt.Errorf("unable to parse pubkey: %v", err)
   512  	}
   513  
   514  	// The signature must be fixed-size LN wire format encoded.
   515  	wireSig, err := lnwire.NewSigFromRawSignature(in.Signature)
   516  	if err != nil {
   517  		return nil, fmt.Errorf("failed to decode signature: %v", err)
   518  	}
   519  	sig, err := wireSig.ToSignature()
   520  	if err != nil {
   521  		return nil, fmt.Errorf("failed to convert from wire format: %v",
   522  			err)
   523  	}
   524  
   525  	// The signature is over the blake256 hash of the message.
   526  	digest := chainhash.HashB(in.Msg)
   527  	valid := sig.Verify(digest, pubkey)
   528  	return &VerifyMessageResp{
   529  		Valid: valid,
   530  	}, nil
   531  }
   532  
   533  // DeriveSharedKey returns a shared secret key by performing Diffie-Hellman key
   534  // derivation between the ephemeral public key in the request and the node's
   535  // key specified in the key_desc parameter. Either a key locator or a raw public
   536  // key is expected in the key_desc, if neither is supplied, defaults to the
   537  // node's identity private key. The old key_loc parameter in the request
   538  // shouldn't be used anymore.
   539  // The resulting shared public key is serialized in the compressed format and
   540  // hashed with sha256, resulting in the final key length of 256bit.
   541  func (s *Server) DeriveSharedKey(_ context.Context, in *SharedKeyRequest) (
   542  	*SharedKeyResponse, error) {
   543  
   544  	// Check that EphemeralPubkey is valid.
   545  	ephemeralPubkey, err := parseRawKeyBytes(in.EphemeralPubkey)
   546  	if err != nil {
   547  		return nil, fmt.Errorf("error in ephemeral pubkey: %v", err)
   548  	}
   549  	if ephemeralPubkey == nil {
   550  		return nil, fmt.Errorf("must provide ephemeral pubkey")
   551  	}
   552  
   553  	// Check for backward compatibility. The caller either specifies the old
   554  	// key_loc field, or the new key_desc field, but not both.
   555  	if in.KeyDesc != nil && in.KeyLoc != nil {
   556  		return nil, fmt.Errorf("use either key_desc or key_loc")
   557  	}
   558  
   559  	// When key_desc is used, the key_desc.key_loc is expected as the caller
   560  	// needs to specify the KeyFamily.
   561  	if in.KeyDesc != nil && in.KeyDesc.KeyLoc == nil {
   562  		return nil, fmt.Errorf("when setting key_desc the field " +
   563  			"key_desc.key_loc must also be set")
   564  	}
   565  
   566  	// We extract two params, rawKeyBytes and keyLoc. Notice their initial
   567  	// values will be overwritten if not using the deprecated RPC param.
   568  	var rawKeyBytes []byte
   569  	keyLoc := in.KeyLoc
   570  	if in.KeyDesc != nil {
   571  		keyLoc = in.KeyDesc.GetKeyLoc()
   572  		rawKeyBytes = in.KeyDesc.GetRawKeyBytes()
   573  	}
   574  
   575  	// When no keyLoc is supplied, defaults to the node's identity private
   576  	// key.
   577  	if keyLoc == nil {
   578  		keyLoc = &KeyLocator{
   579  			KeyFamily: int32(keychain.KeyFamilyNodeKey),
   580  			KeyIndex:  0,
   581  		}
   582  	}
   583  
   584  	// Check the caller is using either the key index or the raw public key
   585  	// to perform the ECDH, we can't have both.
   586  	if rawKeyBytes != nil && keyLoc.KeyIndex != 0 {
   587  		return nil, fmt.Errorf("use either raw_key_bytes or key_index")
   588  	}
   589  
   590  	// Check the raw public key is valid. Notice that if the rawKeyBytes is
   591  	// empty, the parseRawKeyBytes won't return an error, a nil
   592  	// *secp256k1.PublicKey is returned instead.
   593  	pk, err := parseRawKeyBytes(rawKeyBytes)
   594  	if err != nil {
   595  		return nil, fmt.Errorf("error in raw pubkey: %v", err)
   596  	}
   597  
   598  	// Create a key descriptor. When the KeyIndex is not specified, it uses
   599  	// the empty value 0, and when the raw public key is not specified, the
   600  	// pk is nil.
   601  	keyDescriptor := keychain.KeyDescriptor{
   602  		KeyLocator: keychain.KeyLocator{
   603  			Family: keychain.KeyFamily(keyLoc.KeyFamily),
   604  			Index:  uint32(keyLoc.KeyIndex),
   605  		},
   606  		PubKey: pk,
   607  	}
   608  
   609  	// Derive the shared key using ECDH and hashing the serialized
   610  	// compressed shared point.
   611  	sharedKeyHash, err := s.cfg.KeyRing.ECDH(keyDescriptor, ephemeralPubkey)
   612  	if err != nil {
   613  		err := fmt.Errorf("unable to derive shared key: %v", err)
   614  		log.Error(err)
   615  		return nil, err
   616  	}
   617  
   618  	return &SharedKeyResponse{SharedKey: sharedKeyHash[:]}, nil
   619  }
   620  
   621  // parseRawKeyBytes checks that the provided raw public key is valid and returns
   622  // the public key. A nil public key is returned if the length of the rawKeyBytes
   623  // is zero.
   624  func parseRawKeyBytes(rawKeyBytes []byte) (*secp256k1.PublicKey, error) {
   625  	switch {
   626  
   627  	case len(rawKeyBytes) == 33:
   628  		// If a proper raw key was provided, then we'll attempt
   629  		// to decode and parse it.
   630  		return secp256k1.ParsePubKey(
   631  			rawKeyBytes,
   632  		)
   633  
   634  	case len(rawKeyBytes) == 0:
   635  		// No key is provided, return nil.
   636  		return nil, nil
   637  
   638  	default:
   639  		// If the user provided a raw key, but it's of the
   640  		// wrong length, then we'll return with an error.
   641  		return nil, fmt.Errorf("pubkey must be " +
   642  			"serialized in compressed format if " +
   643  			"specified")
   644  	}
   645  }