1 // Copyright 2021 Google LLC 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/jwt/internal/raw_jwt_ecdsa_sign_key_manager.h" 18 19 #include <memory> 20 #include <string> 21 #include <utility> 22 23 #include "absl/memory/memory.h" 24 #include "absl/strings/string_view.h" 25 #include "tink/internal/ec_util.h" 26 #include "tink/jwt/internal/raw_jwt_ecdsa_verify_key_manager.h" 27 #include "tink/public_key_sign.h" 28 #include "tink/subtle/ecdsa_sign_boringssl.h" 29 #include "tink/util/enums.h" 30 #include "tink/util/errors.h" 31 #include "tink/util/protobuf_helper.h" 32 #include "tink/util/secret_data.h" 33 #include "tink/util/status.h" 34 #include "tink/util/statusor.h" 35 #include "tink/util/validation.h" 36 #include "proto/jwt_ecdsa.pb.h" 37 38 namespace crypto { 39 namespace tink { 40 namespace jwt_internal { 41 42 using crypto::tink::util::Enums; 43 using crypto::tink::util::Status; 44 using crypto::tink::util::StatusOr; 45 using google::crypto::tink::JwtEcdsaKeyFormat; 46 using google::crypto::tink::JwtEcdsaPrivateKey; 47 using google::crypto::tink::JwtEcdsaPublicKey; 48 CreateKey(const JwtEcdsaKeyFormat & jwt_ecdsa_key_format) const49StatusOr<JwtEcdsaPrivateKey> RawJwtEcdsaSignKeyManager::CreateKey( 50 const JwtEcdsaKeyFormat& jwt_ecdsa_key_format) const { 51 // Generate new EC key. 52 util::StatusOr<google::crypto::tink::EllipticCurveType> curve = 53 RawJwtEcdsaVerifyKeyManager::CurveForEcdsaAlgorithm( 54 jwt_ecdsa_key_format.algorithm()); 55 if (!curve.ok()) { 56 return curve.status(); 57 } 58 59 util::StatusOr<internal::EcKey> ec_key = 60 internal::NewEcKey(util::Enums::ProtoToSubtle(*curve)); 61 if (!ec_key.ok()) return ec_key.status(); 62 63 // Build EcdsaPrivateKey. 64 JwtEcdsaPrivateKey jwt_ecdsa_private_key; 65 jwt_ecdsa_private_key.set_version(get_version()); 66 jwt_ecdsa_private_key.set_key_value( 67 std::string(util::SecretDataAsStringView(ec_key->priv))); 68 auto jwt_ecdsa_public_key = jwt_ecdsa_private_key.mutable_public_key(); 69 jwt_ecdsa_public_key->set_version(get_version()); 70 jwt_ecdsa_public_key->set_x(ec_key->pub_x); 71 jwt_ecdsa_public_key->set_y(ec_key->pub_y); 72 jwt_ecdsa_public_key->set_algorithm(jwt_ecdsa_key_format.algorithm()); 73 return jwt_ecdsa_private_key; 74 } 75 76 StatusOr<std::unique_ptr<PublicKeySign>> Create(const JwtEcdsaPrivateKey & jwt_ecdsa_private_key) const77RawJwtEcdsaSignKeyManager::PublicKeySignFactory::Create( 78 const JwtEcdsaPrivateKey& jwt_ecdsa_private_key) const { 79 const JwtEcdsaPublicKey& public_key = jwt_ecdsa_private_key.public_key(); 80 internal::EcKey ec_key; 81 util::StatusOr<google::crypto::tink::EllipticCurveType> curve = 82 RawJwtEcdsaVerifyKeyManager::CurveForEcdsaAlgorithm( 83 public_key.algorithm()); 84 if (!curve.ok()) { 85 return curve.status(); 86 } 87 ec_key.curve = Enums::ProtoToSubtle(*curve); 88 ec_key.pub_x = public_key.x(); 89 ec_key.pub_y = public_key.y(); 90 ec_key.priv = 91 util::SecretDataFromStringView(jwt_ecdsa_private_key.key_value()); 92 util::StatusOr<google::crypto::tink::HashType> hash_type = 93 RawJwtEcdsaVerifyKeyManager::HashForEcdsaAlgorithm( 94 public_key.algorithm()); 95 if (!hash_type.ok()) { 96 return hash_type.status(); 97 } 98 auto result = subtle::EcdsaSignBoringSsl::New( 99 ec_key, Enums::ProtoToSubtle(*hash_type), 100 subtle::EcdsaSignatureEncoding::IEEE_P1363); 101 if (!result.ok()) return result.status(); 102 return {*std::move(result)}; 103 } 104 ValidateKey(const JwtEcdsaPrivateKey & key) const105Status RawJwtEcdsaSignKeyManager::ValidateKey( 106 const JwtEcdsaPrivateKey& key) const { 107 Status status = ValidateVersion(key.version(), get_version()); 108 if (!status.ok()) return status; 109 return RawJwtEcdsaVerifyKeyManager().ValidateKey(key.public_key()); 110 } 111 ValidateKeyFormat(const JwtEcdsaKeyFormat & key_format) const112Status RawJwtEcdsaSignKeyManager::ValidateKeyFormat( 113 const JwtEcdsaKeyFormat& key_format) const { 114 return RawJwtEcdsaVerifyKeyManager::ValidateAlgorithm(key_format.algorithm()); 115 } 116 117 } // namespace jwt_internal 118 } // namespace tink 119 } // namespace crypto 120