1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chromeos/login/auth/challenge_response/cert_utils.h" 6 7 #include <string> 8 9 #include "base/logging.h" 10 #include "base/strings/string_piece.h" 11 #include "net/cert/asn1_util.h" 12 #include "net/cert/x509_certificate.h" 13 #include "net/cert/x509_util.h" 14 #include "third_party/boringssl/src/include/openssl/ssl.h" 15 16 namespace chromeos { 17 18 namespace { 19 GetSubjectPublicKeyInfo(const net::X509Certificate & certificate,std::string * spki_der)20bool GetSubjectPublicKeyInfo(const net::X509Certificate& certificate, 21 std::string* spki_der) { 22 base::StringPiece spki_der_piece; 23 if (!net::asn1::ExtractSPKIFromDERCert( 24 net::x509_util::CryptoBufferAsStringPiece(certificate.cert_buffer()), 25 &spki_der_piece)) { 26 return false; 27 } 28 *spki_der = spki_der_piece.as_string(); 29 return !spki_der->empty(); 30 } 31 32 } // namespace 33 34 base::Optional<ChallengeResponseKey::SignatureAlgorithm> GetChallengeResponseKeyAlgorithmFromSsl(uint16_t ssl_algorithm)35GetChallengeResponseKeyAlgorithmFromSsl(uint16_t ssl_algorithm) { 36 switch (ssl_algorithm) { 37 case SSL_SIGN_RSA_PKCS1_SHA1: 38 return ChallengeResponseKey::SignatureAlgorithm::kRsassaPkcs1V15Sha1; 39 case SSL_SIGN_RSA_PKCS1_SHA256: 40 return ChallengeResponseKey::SignatureAlgorithm::kRsassaPkcs1V15Sha256; 41 case SSL_SIGN_RSA_PKCS1_SHA384: 42 return ChallengeResponseKey::SignatureAlgorithm::kRsassaPkcs1V15Sha384; 43 case SSL_SIGN_RSA_PKCS1_SHA512: 44 return ChallengeResponseKey::SignatureAlgorithm::kRsassaPkcs1V15Sha512; 45 default: 46 // This algorithm is unsupported by ChallengeResponseKey. 47 return {}; 48 } 49 } 50 ExtractChallengeResponseKeyFromCert(const net::X509Certificate & certificate,const std::vector<ChallengeResponseKey::SignatureAlgorithm> & signature_algorithms,ChallengeResponseKey * challenge_response_key)51bool ExtractChallengeResponseKeyFromCert( 52 const net::X509Certificate& certificate, 53 const std::vector<ChallengeResponseKey::SignatureAlgorithm>& 54 signature_algorithms, 55 ChallengeResponseKey* challenge_response_key) { 56 if (signature_algorithms.empty()) { 57 LOG(ERROR) 58 << "No signature algorithms provided for the challenge-response key"; 59 return false; 60 } 61 std::string spki_der; 62 if (!GetSubjectPublicKeyInfo(certificate, &spki_der)) { 63 LOG(ERROR) << "Failed to extract Subject Public Key Information from the " 64 "given certificate"; 65 return false; 66 } 67 challenge_response_key->set_public_key_spki_der(spki_der); 68 challenge_response_key->set_signature_algorithms(signature_algorithms); 69 return true; 70 } 71 72 } // namespace chromeos 73