certificate_checker.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. //
  2. // Copyright (C) 2011 The Android Open Source Project
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. #ifndef UPDATE_ENGINE_CERTIFICATE_CHECKER_H_
  17. #define UPDATE_ENGINE_CERTIFICATE_CHECKER_H_
  18. #include <curl/curl.h>
  19. #include <openssl/ssl.h>
  20. #include <string>
  21. #include <base/macros.h>
  22. #include <gtest/gtest_prod.h> // for FRIEND_TEST
  23. namespace chromeos_update_engine {
  24. class PrefsInterface;
  25. // Wrapper for openssl operations with the certificates.
  26. class OpenSSLWrapper {
  27. public:
  28. OpenSSLWrapper() = default;
  29. virtual ~OpenSSLWrapper() = default;
  30. // Takes an openssl X509_STORE_CTX, extracts the corresponding certificate
  31. // from it and calculates its fingerprint (SHA256 digest). Returns true on
  32. // success and false otherwise.
  33. //
  34. // |x509_ctx| is the pointer to the openssl object that holds the certificate.
  35. // |out_depth| is the depth of the current certificate, in the certificate
  36. // chain.
  37. // |out_digest_length| is the length of the generated digest.
  38. // |out_digest| is the byte array where the digest itself will be written.
  39. // It should be big enough to hold a SHA1 digest (e.g. EVP_MAX_MD_SIZE).
  40. virtual bool GetCertificateDigest(X509_STORE_CTX* x509_ctx,
  41. int* out_depth,
  42. unsigned int* out_digest_length,
  43. uint8_t* out_digest) const;
  44. private:
  45. DISALLOW_COPY_AND_ASSIGN(OpenSSLWrapper);
  46. };
  47. // The values in this enum are replicated in the metrics server. See metrics.h
  48. // for instructions on how to update these values in the server side.
  49. enum class CertificateCheckResult {
  50. // The certificate is valid and the same as seen before or the first time we
  51. // see a certificate.
  52. kValid,
  53. // The certificate is valid, but is different than a previously seen
  54. // certificate for the selected server.
  55. kValidChanged,
  56. // The certificate validation failed.
  57. kFailed,
  58. // This value must be the last entry.
  59. kNumConstants
  60. };
  61. // These values are used to generate the keys of files persisted via prefs.
  62. // This means that changing these will cause loss of information on metrics
  63. // reporting, during the transition. These values are also mapped to a metric
  64. // name in metrics.cc, so adding values here requires to assign a new metric
  65. // name in that file.
  66. enum class ServerToCheck {
  67. kUpdate = 0,
  68. kDownload,
  69. // Ignore this server.
  70. kNone,
  71. };
  72. // Responsible for checking whether update server certificates change, and
  73. // reporting to UMA when this happens. Since all state information is persisted,
  74. // and openssl forces us to use a static callback with no data pointer, this
  75. // class is entirely static.
  76. class CertificateChecker {
  77. public:
  78. class Observer {
  79. public:
  80. virtual ~Observer() = default;
  81. // Called whenever a certificate is checked for the server |server_to_check|
  82. // passing the result of said certificate check.
  83. virtual void CertificateChecked(ServerToCheck server_to_check,
  84. CertificateCheckResult result) = 0;
  85. };
  86. CertificateChecker(PrefsInterface* prefs, OpenSSLWrapper* openssl_wrapper);
  87. ~CertificateChecker();
  88. // This callback is called by libcurl just before the initialization of an
  89. // SSL connection after having processed all other SSL related options. Used
  90. // to check if server certificates change. |cert_checker| is expected to be a
  91. // pointer to the CertificateChecker instance.
  92. static CURLcode ProcessSSLContext(CURL* curl_handle,
  93. SSL_CTX* ssl_ctx,
  94. void* cert_checker);
  95. // Initialize this class as the singleton instance. Only one instance can be
  96. // initialized at a time and it should be initialized before other methods
  97. // can be used.
  98. void Init();
  99. // Set the certificate observer to the passed instance. To remove the
  100. // observer, pass a nullptr. The |observer| instance must be valid while this
  101. // CertificateChecker verifies certificates.
  102. void SetObserver(Observer* observer) { observer_ = observer; }
  103. private:
  104. FRIEND_TEST(CertificateCheckerTest, NewCertificate);
  105. FRIEND_TEST(CertificateCheckerTest, SameCertificate);
  106. FRIEND_TEST(CertificateCheckerTest, ChangedCertificate);
  107. FRIEND_TEST(CertificateCheckerTest, FailedCertificate);
  108. // These callbacks are asynchronously called by openssl after initial SSL
  109. // verification. They are used to perform any additional security verification
  110. // on the connection, but we use them here to get hold of the server
  111. // certificate, in order to determine if it has changed since the last
  112. // connection. Since openssl forces us to do this statically, we define two
  113. // different callbacks for the two different official update servers, and only
  114. // assign the correspondent one. The assigned callback is then called once per
  115. // each certificate on the server and returns 1 for success and 0 for failure.
  116. static int VerifySSLCallbackDownload(int preverify_ok,
  117. X509_STORE_CTX* x509_ctx);
  118. static int VerifySSLCallbackUpdate(int preverify_ok,
  119. X509_STORE_CTX* x509_ctx);
  120. static int VerifySSLCallback(int preverify_ok,
  121. X509_STORE_CTX* x509_ctx,
  122. ServerToCheck server_to_check);
  123. // Checks if server certificate stored in |x509_ctx| has changed since last
  124. // connection to that same server, specified by |server_to_check|.
  125. // This is called by the callbacks defined above. The result of the
  126. // certificate check is passed to the observer, if any. Returns true on
  127. // success and false otherwise.
  128. bool CheckCertificateChange(int preverify_ok,
  129. X509_STORE_CTX* x509_ctx,
  130. ServerToCheck server_to_check);
  131. // Notifies the observer, if any, of a certificate checking.
  132. void NotifyCertificateChecked(ServerToCheck server_to_check,
  133. CertificateCheckResult result);
  134. // The CertificateChecker singleton instance.
  135. static CertificateChecker* cert_checker_singleton_;
  136. // Prefs instance used to store the certificates seen in the past.
  137. PrefsInterface* prefs_;
  138. // The wrapper for openssl operations.
  139. OpenSSLWrapper* openssl_wrapper_;
  140. // The observer called whenever a certificate is checked, if not null.
  141. Observer* observer_{nullptr};
  142. DISALLOW_COPY_AND_ASSIGN(CertificateChecker);
  143. };
  144. } // namespace chromeos_update_engine
  145. #endif // UPDATE_ENGINE_CERTIFICATE_CHECKER_H_