remotesigner.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. *
  3. * Copyright 2022 Google LLC
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * https://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. // Package remotesigner offloads private key operations to S2Av2.
  19. package remotesigner
  20. import (
  21. "crypto"
  22. "crypto/rsa"
  23. "crypto/x509"
  24. "fmt"
  25. "io"
  26. "github.com/google/s2a-go/stream"
  27. "google.golang.org/grpc/codes"
  28. "google.golang.org/grpc/grpclog"
  29. s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto"
  30. )
  31. // remoteSigner implementes the crypto.Signer interface.
  32. type remoteSigner struct {
  33. leafCert *x509.Certificate
  34. s2AStream stream.S2AStream
  35. }
  36. // New returns an instance of RemoteSigner, an implementation of the
  37. // crypto.Signer interface.
  38. func New(leafCert *x509.Certificate, s2AStream stream.S2AStream) crypto.Signer {
  39. return &remoteSigner{leafCert, s2AStream}
  40. }
  41. func (s *remoteSigner) Public() crypto.PublicKey {
  42. return s.leafCert.PublicKey
  43. }
  44. func (s *remoteSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
  45. signatureAlgorithm, err := getSignatureAlgorithm(opts, s.leafCert)
  46. if err != nil {
  47. return nil, err
  48. }
  49. req, err := getSignReq(signatureAlgorithm, digest)
  50. if err != nil {
  51. return nil, err
  52. }
  53. if grpclog.V(1) {
  54. grpclog.Infof("Sending request to S2Av2 for signing operation.")
  55. }
  56. if err := s.s2AStream.Send(&s2av2pb.SessionReq{
  57. ReqOneof: &s2av2pb.SessionReq_OffloadPrivateKeyOperationReq{
  58. OffloadPrivateKeyOperationReq: req,
  59. },
  60. }); err != nil {
  61. grpclog.Infof("Failed to send request to S2Av2 for signing operation.")
  62. return nil, err
  63. }
  64. resp, err := s.s2AStream.Recv()
  65. if err != nil {
  66. grpclog.Infof("Failed to receive signing operation response from S2Av2.")
  67. return nil, err
  68. }
  69. if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) {
  70. return nil, fmt.Errorf("failed to offload signing with private key to S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details)
  71. }
  72. return resp.GetOffloadPrivateKeyOperationResp().GetOutBytes(), nil
  73. }
  74. // getCert returns the leafCert field in s.
  75. func (s *remoteSigner) getCert() *x509.Certificate {
  76. return s.leafCert
  77. }
  78. // getStream returns the s2AStream field in s.
  79. func (s *remoteSigner) getStream() stream.S2AStream {
  80. return s.s2AStream
  81. }
  82. func getSignReq(signatureAlgorithm s2av2pb.SignatureAlgorithm, digest []byte) (*s2av2pb.OffloadPrivateKeyOperationReq, error) {
  83. if (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA256) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256) {
  84. return &s2av2pb.OffloadPrivateKeyOperationReq{
  85. Operation: s2av2pb.OffloadPrivateKeyOperationReq_SIGN,
  86. SignatureAlgorithm: signatureAlgorithm,
  87. InBytes: &s2av2pb.OffloadPrivateKeyOperationReq_Sha256Digest{
  88. Sha256Digest: digest,
  89. },
  90. }, nil
  91. } else if (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA384) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384) {
  92. return &s2av2pb.OffloadPrivateKeyOperationReq{
  93. Operation: s2av2pb.OffloadPrivateKeyOperationReq_SIGN,
  94. SignatureAlgorithm: signatureAlgorithm,
  95. InBytes: &s2av2pb.OffloadPrivateKeyOperationReq_Sha384Digest{
  96. Sha384Digest: digest,
  97. },
  98. }, nil
  99. } else if (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA512) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ED25519) {
  100. return &s2av2pb.OffloadPrivateKeyOperationReq{
  101. Operation: s2av2pb.OffloadPrivateKeyOperationReq_SIGN,
  102. SignatureAlgorithm: signatureAlgorithm,
  103. InBytes: &s2av2pb.OffloadPrivateKeyOperationReq_Sha512Digest{
  104. Sha512Digest: digest,
  105. },
  106. }, nil
  107. } else {
  108. return nil, fmt.Errorf("unknown signature algorithm: %v", signatureAlgorithm)
  109. }
  110. }
  111. // getSignatureAlgorithm returns the signature algorithm that S2A must use when
  112. // performing a signing operation that has been offloaded by an application
  113. // using the crypto/tls libraries.
  114. func getSignatureAlgorithm(opts crypto.SignerOpts, leafCert *x509.Certificate) (s2av2pb.SignatureAlgorithm, error) {
  115. if opts == nil || leafCert == nil {
  116. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm")
  117. }
  118. switch leafCert.PublicKeyAlgorithm {
  119. case x509.RSA:
  120. if rsaPSSOpts, ok := opts.(*rsa.PSSOptions); ok {
  121. return rsaPSSAlgorithm(rsaPSSOpts)
  122. }
  123. return rsaPPKCS1Algorithm(opts)
  124. case x509.ECDSA:
  125. return ecdsaAlgorithm(opts)
  126. case x509.Ed25519:
  127. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ED25519, nil
  128. default:
  129. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm: %q", leafCert.PublicKeyAlgorithm)
  130. }
  131. }
  132. func rsaPSSAlgorithm(opts *rsa.PSSOptions) (s2av2pb.SignatureAlgorithm, error) {
  133. switch opts.HashFunc() {
  134. case crypto.SHA256:
  135. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256, nil
  136. case crypto.SHA384:
  137. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384, nil
  138. case crypto.SHA512:
  139. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512, nil
  140. default:
  141. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm")
  142. }
  143. }
  144. func rsaPPKCS1Algorithm(opts crypto.SignerOpts) (s2av2pb.SignatureAlgorithm, error) {
  145. switch opts.HashFunc() {
  146. case crypto.SHA256:
  147. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA256, nil
  148. case crypto.SHA384:
  149. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA384, nil
  150. case crypto.SHA512:
  151. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA512, nil
  152. default:
  153. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm")
  154. }
  155. }
  156. func ecdsaAlgorithm(opts crypto.SignerOpts) (s2av2pb.SignatureAlgorithm, error) {
  157. switch opts.HashFunc() {
  158. case crypto.SHA256:
  159. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256, nil
  160. case crypto.SHA384:
  161. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384, nil
  162. case crypto.SHA512:
  163. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512, nil
  164. default:
  165. return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm")
  166. }
  167. }