| // Copyright 2021 The Cobalt Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "starboard/shared/deviceauth/deviceauth_internal.h" |
| |
| #include <string.h> |
| #include <string> |
| |
| #include "starboard/common/log.h" |
| #include "starboard/linux/x64x11/system_properties.h" |
| #include "starboard/system.h" |
| #include "third_party/boringssl/src/include/openssl/hmac.h" |
| #include "third_party/modp_b64/modp_b64.h" |
| namespace { |
| bool Base64Decode(const std::string& input, std::string* output) { |
| std::string temp; |
| temp.resize(modp_b64_decode_len(input.size())); |
| |
| // does not null terminate result since result is binary data! |
| size_t input_size = input.size(); |
| int output_size = modp_b64_decode(&(temp[0]), input.data(), input_size); |
| if (output_size == MODP_B64_ERROR) |
| return false; |
| |
| temp.resize(output_size); |
| output->swap(temp); |
| return true; |
| } |
| } // namespace |
| |
| namespace starboard { |
| namespace shared { |
| namespace deviceauth { |
| |
| // This function is meant to exist purely for reference. |
| // |
| // Implementation that uses a compiled-in key. |
| // The application may already fallback to querying for the secret key and |
| // applying this same logic if this function returns false. Because of that, |
| // if you are considering using this implementation in production, it's quite |
| // possible that simply using the stub version of this function would work |
| // just as well for you. A more production-ready version of this function might |
| // forward to an internal API that signs the message in a hardware-backed secure |
| // keystore. |
| bool SignWithCertificationSecretKey(const char* secret_key, |
| const uint8_t* message, |
| size_t message_size_in_bytes, |
| uint8_t* digest, |
| size_t digest_size_in_bytes) { |
| if (digest_size_in_bytes < 32) { |
| SB_LOG(ERROR) << "SbSystemSignWithCertificationSecretKey() must be called " |
| << "with an output digest buffer size of at least 32 bytes."; |
| return false; |
| } |
| const size_t kBase64EncodedCertificationSecretLength = 1023; |
| char base_64_secret_property[kBase64EncodedCertificationSecretLength + 1] = { |
| 0}; |
| strncpy(base_64_secret_property, kBase64EncodedCertificationSecret, |
| kBase64EncodedCertificationSecretLength); |
| |
| std::string secret; |
| SB_CHECK(Base64Decode(base_64_secret_property, &secret)); |
| |
| uint8_t* result = HMAC(EVP_sha256(), secret.data(), secret.size(), message, |
| message_size_in_bytes, digest, nullptr); |
| |
| return result == digest; |
| } |
| |
| } // namespace deviceauth |
| } // namespace shared |
| } // namespace starboard |