1 // Copyright (c) 2012 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 "net/cert/cert_verify_proc_android.h" 6 7 #include <string> 8 #include <vector> 9 10 #include "base/logging.h" 11 #include "net/android/cert_verify_result_android.h" 12 #include "net/android/network_library.h" 13 #include "net/base/net_errors.h" 14 #include "net/cert/cert_status_flags.h" 15 #include "net/cert/cert_verify_result.h" 16 #include "net/cert/x509_certificate.h" 17 18 namespace net { 19 20 namespace { 21 22 // Returns true if the certificate verification call was successful (regardless 23 // of its result), i.e. if |verify_result| was set. Otherwise returns false. 24 bool VerifyFromAndroidTrustManager(const std::vector<std::string>& cert_bytes, 25 CertVerifyResult* verify_result) { 26 // TODO(joth): Fetch the authentication type from SSL rather than hardcode. 27 android::CertVerifyResultAndroid android_result = 28 android::VerifyX509CertChain(cert_bytes, "RSA"); 29 switch (android_result) { 30 case android::VERIFY_FAILED: 31 return false; 32 case android::VERIFY_OK: 33 break; 34 case android::VERIFY_NO_TRUSTED_ROOT: 35 verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID; 36 break; 37 case android::VERIFY_EXPIRED: 38 case android::VERIFY_NOT_YET_VALID: 39 verify_result->cert_status |= CERT_STATUS_DATE_INVALID; 40 break; 41 case android::VERIFY_UNABLE_TO_PARSE: 42 verify_result->cert_status |= CERT_STATUS_INVALID; 43 break; 44 case android::VERIFY_INCORRECT_KEY_USAGE: 45 verify_result->cert_status |= CERT_STATUS_INVALID; 46 break; 47 default: 48 NOTREACHED(); 49 verify_result->cert_status |= CERT_STATUS_INVALID; 50 break; 51 } 52 return true; 53 } 54 55 bool GetChainDEREncodedBytes(X509Certificate* cert, 56 std::vector<std::string>* chain_bytes) { 57 X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); 58 X509Certificate::OSCertHandles cert_handles = 59 cert->GetIntermediateCertificates(); 60 61 // Make sure the peer's own cert is the first in the chain, if it's not 62 // already there. 63 if (cert_handles.empty() || cert_handles[0] != cert_handle) 64 cert_handles.insert(cert_handles.begin(), cert_handle); 65 66 chain_bytes->reserve(cert_handles.size()); 67 for (X509Certificate::OSCertHandles::const_iterator it = 68 cert_handles.begin(); it != cert_handles.end(); ++it) { 69 std::string cert_bytes; 70 if(!X509Certificate::GetDEREncoded(*it, &cert_bytes)) 71 return false; 72 chain_bytes->push_back(cert_bytes); 73 } 74 return true; 75 } 76 77 } // namespace 78 79 CertVerifyProcAndroid::CertVerifyProcAndroid() {} 80 81 CertVerifyProcAndroid::~CertVerifyProcAndroid() {} 82 83 bool CertVerifyProcAndroid::SupportsAdditionalTrustAnchors() const { 84 return false; 85 } 86 87 int CertVerifyProcAndroid::VerifyInternal( 88 X509Certificate* cert, 89 const std::string& hostname, 90 int flags, 91 CRLSet* crl_set, 92 const CertificateList& additional_trust_anchors, 93 CertVerifyResult* verify_result) { 94 if (!cert->VerifyNameMatch(hostname, 95 &verify_result->common_name_fallback_used)) { 96 verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID; 97 } 98 99 std::vector<std::string> cert_bytes; 100 if (!GetChainDEREncodedBytes(cert, &cert_bytes)) 101 return ERR_CERT_INVALID; 102 if (!VerifyFromAndroidTrustManager(cert_bytes, verify_result)) { 103 NOTREACHED(); 104 return ERR_FAILED; 105 } 106 if (IsCertStatusError(verify_result->cert_status)) 107 return MapCertStatusToNetError(verify_result->cert_status); 108 109 // TODO(ppi): Implement missing functionality: yielding the constructed trust 110 // chain, public key hashes of its certificates and |is_issued_by_known_root| 111 // flag. All of the above require specific support from the platform, missing 112 // in the Java APIs. See also: http://crbug.com/116838 113 114 // Until the required support is available in the platform, we don't know if 115 // the trust root at the end of the chain was standard or user-added, so we 116 // mark all correctly verified certificates as issued by a known root. 117 verify_result->is_issued_by_known_root = true; 118 119 return OK; 120 } 121 122 } // namespace net 123