Chromium Code Reviews| Index: net/third_party/nss/ssl/cmpcert.cc |
| diff --git a/net/third_party/nss/ssl/cmpcert.cc b/net/third_party/nss/ssl/cmpcert.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1b3252b455fcce15e4478d8ec9a032de386ac5eb |
| --- /dev/null |
| +++ b/net/third_party/nss/ssl/cmpcert.cc |
| @@ -0,0 +1,75 @@ |
| +/* |
| + * NSS utility functions |
| + * |
| + * This Source Code Form is subject to the terms of the Mozilla Public |
| + * License, v. 2.0. If a copy of the MPL was not distributed with this |
| + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| + |
| +#include "net/third_party/nss/ssl/cmpcert.h" |
| + |
| +#include <secder.h> |
| +#include <secitem.h> |
| + |
| +#include "base/logging.h" |
| +#include "base/strings/string_piece.h" |
| + |
| +namespace net { |
| + |
| +bool MatchClientCertificateIssuers( |
| + CERTCertificate* cert, |
| + const std::vector<std::string>& cert_authorities, |
| + std::vector<ScopedCERTCertificate>* chain) { |
| + // Bound how many iterations to try. |
| + static const int kMaxDepth = 20; |
| + |
| + // Retain the full certificate chain. Some deployments expect the client to |
| + // supply intermediates out of the local store. https://crbug.com/548631 |
| + chain->clear(); |
| + chain->emplace_back(CERT_DupCertificate(cert)); |
| + |
| + // If no authorities are supplied, everything matches. |
| + if (cert_authorities.empty()) |
| + return true; |
| + |
| + while (chain->size() < kMaxDepth) { |
| + CERTCertificate* curcert = chain->back().get(); |
| + |
| + base::StringPiece issuer( |
| + reinterpret_cast<const char*>(curcert->derIssuer.data), |
| + curcert->derIssuer.len); |
| + |
| + // Compute an alternate issuer name for compatibility with 2.0 enterprise |
| + // server, which send the CA names without the outer layer of DER header. |
| + // |
| + // TODO(davidben): Can this be removed? |
|
Ryan Sleevi
2016/07/29 00:37:44
Yup. No other platforms have this.
davidben
2016/07/29 15:14:11
Removed.
At this point this function can only pas
|
| + base::StringPiece compat_issuer; |
| + int header_len; |
| + PRUint32 content_len; |
| + if (DER_Lengths(&curcert->derIssuer, &header_len, &content_len) == |
| + SECSuccess) |
| + compat_issuer = issuer.substr(header_len); |
| + |
| + // Check if |curcert| is signed by a valid CA. |
| + for (const std::string& ca : cert_authorities) { |
| + if (issuer == ca || (!compat_issuer.empty() && compat_issuer == ca)) |
| + return true; |
| + } |
| + |
| + // Stop at self-issued certificates. |
| + if (SECITEM_CompareItem(&curcert->derIssuer, &curcert->derSubject) == |
| + SECEqual) { |
| + return false; |
| + } |
| + |
| + // Look the parent up in the database and keep searching. |
| + CERTCertificate* parent = |
| + CERT_FindCertByName(curcert->dbhandle, &curcert->derIssuer); |
| + if (!parent) |
| + return false; |
| + chain->emplace_back(parent); |
| + } |
| + |
| + return false; |
| +} |
| + |
| +} // namespace net |