• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 Google Inc.
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 ///////////////////////////////////////////////////////////////////////////////
16 
17 #include "tink/subtle/ecdsa_sign_boringssl.h"
18 
19 #include <memory>
20 #include <string>
21 #include <utility>
22 #include <vector>
23 
24 #include "absl/status/status.h"
25 #include "openssl/evp.h"
26 #include "tink/internal/md_util.h"
27 #include "tink/internal/util.h"
28 #include "tink/signature/internal/ecdsa_raw_sign_boringssl.h"
29 #include "tink/subtle/common_enums.h"
30 #include "tink/subtle/subtle_util_boringssl.h"
31 #include "tink/util/statusor.h"
32 
33 namespace crypto {
34 namespace tink {
35 namespace subtle {
36 
New(const SubtleUtilBoringSSL::EcKey & ec_key,HashType hash_type,EcdsaSignatureEncoding encoding)37 util::StatusOr<std::unique_ptr<EcdsaSignBoringSsl>> EcdsaSignBoringSsl::New(
38     const SubtleUtilBoringSSL::EcKey& ec_key, HashType hash_type,
39     EcdsaSignatureEncoding encoding) {
40   auto status = internal::CheckFipsCompatibility<EcdsaSignBoringSsl>();
41   if (!status.ok()) return status;
42 
43   // Check if the hash type is safe to use.
44   util::Status is_safe = internal::IsHashTypeSafeForSignature(hash_type);
45   if (!is_safe.ok()) {
46     return is_safe;
47   }
48   util::StatusOr<const EVP_MD*> hash = internal::EvpHashFromHashType(hash_type);
49   if (!hash.ok()) {
50     return hash.status();
51   }
52 
53   util::StatusOr<std::unique_ptr<internal::EcdsaRawSignBoringSsl>> raw_sign =
54       internal::EcdsaRawSignBoringSsl::New(ec_key, encoding);
55   if (!raw_sign.ok()) return raw_sign.status();
56 
57   return {
58       absl::WrapUnique(new EcdsaSignBoringSsl(*hash, std::move(*raw_sign)))};
59 }
60 
Sign(absl::string_view data) const61 util::StatusOr<std::string> EcdsaSignBoringSsl::Sign(
62     absl::string_view data) const {
63   // BoringSSL expects a non-null pointer for data,
64   // regardless of whether the size is 0.
65   data = internal::EnsureStringNonNull(data);
66 
67   // Compute the digest.
68   unsigned int digest_size;
69   uint8_t digest[EVP_MAX_MD_SIZE];
70   if (1 != EVP_Digest(data.data(), data.size(), digest, &digest_size, hash_,
71                       nullptr)) {
72     return util::Status(absl::StatusCode::kInternal,
73                         "Could not compute digest.");
74   }
75 
76   // Compute the signature.
77   return raw_signer_->Sign(
78       absl::string_view(reinterpret_cast<char*>(digest), digest_size));
79 }
80 
81 }  // namespace subtle
82 }  // namespace tink
83 }  // namespace crypto
84