blob: 13bb5ff14ae2c56bb60772deace69d536e5c7c0b [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_
#define QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_
#include <istream>
#include <memory>
#include <vector>
#include "third_party/boringssl/src/include/openssl/base.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/evp.h"
#include "net/third_party/quiche/src/quic/core/crypto/boring_utils.h"
#include "net/third_party/quiche/src/quic/core/quic_time.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
namespace quic {
struct QUIC_EXPORT_PRIVATE PemReadResult {
enum Status { kOk, kEof, kError };
Status status;
std::string contents;
// The type of the PEM message (e.g., if the message starts with
// "-----BEGIN CERTIFICATE-----", the |type| would be "CERTIFICATE").
std::string type;
};
// Reads |input| line-by-line and returns the next available PEM message.
QUIC_EXPORT_PRIVATE PemReadResult ReadNextPemMessage(std::istream* input);
// CertificateView represents a parsed version of a single X.509 certificate. As
// the word "view" implies, it does not take ownership of the underlying strings
// and consists primarily of pointers into the certificate that is passed into
// the parser.
class QUIC_EXPORT_PRIVATE CertificateView {
public:
// Parses a single DER-encoded X.509 certificate. Returns nullptr on parse
// error.
static std::unique_ptr<CertificateView> ParseSingleCertificate(
quiche::QuicheStringPiece certificate);
// Loads all PEM-encoded X.509 certificates found in the |input| stream
// without parsing them. Returns an empty vector if any parsing error occurs.
static std::vector<std::string> LoadPemFromStream(std::istream* input);
QuicWallTime validity_start() const { return validity_start_; }
QuicWallTime validity_end() const { return validity_end_; }
const EVP_PKEY* public_key() const { return public_key_.get(); }
const std::vector<quiche::QuicheStringPiece>& subject_alt_name_domains()
const {
return subject_alt_name_domains_;
}
const std::vector<QuicIpAddress>& subject_alt_name_ips() const {
return subject_alt_name_ips_;
}
// |signature_algorithm| is a TLS signature algorithm ID.
bool VerifySignature(quiche::QuicheStringPiece data,
quiche::QuicheStringPiece signature,
uint16_t signature_algorithm) const;
private:
CertificateView() = default;
QuicWallTime validity_start_ = QuicWallTime::Zero();
QuicWallTime validity_end_ = QuicWallTime::Zero();
// Public key parsed from SPKI.
bssl::UniquePtr<EVP_PKEY> public_key_;
// SubjectAltName, https://tools.ietf.org/html/rfc5280#section-4.2.1.6
std::vector<quiche::QuicheStringPiece> subject_alt_name_domains_;
std::vector<QuicIpAddress> subject_alt_name_ips_;
// Called from ParseSingleCertificate().
bool ParseExtensions(CBS extensions);
bool ValidatePublicKeyParameters();
};
// CertificatePrivateKey represents a private key that can be used with an X.509
// certificate.
class QUIC_EXPORT_PRIVATE CertificatePrivateKey {
public:
// Loads a DER-encoded PrivateKeyInfo structure (RFC 5958) as a private key.
static std::unique_ptr<CertificatePrivateKey> LoadFromDer(
quiche::QuicheStringPiece private_key);
// Loads a private key from a PEM file formatted according to RFC 7468. Also
// supports legacy OpenSSL RSA key format ("BEGIN RSA PRIVATE KEY").
static std::unique_ptr<CertificatePrivateKey> LoadPemFromStream(
std::istream* input);
// |signature_algorithm| is a TLS signature algorithm ID.
std::string Sign(quiche::QuicheStringPiece input,
uint16_t signature_algorithm);
// Verifies that the private key in question matches the public key of the
// certificate |view|.
bool MatchesPublicKey(const CertificateView& view);
private:
CertificatePrivateKey() = default;
bssl::UniquePtr<EVP_PKEY> private_key_;
};
// Parses a DER time based on the specified ASN.1 tag. Exposed primarily for
// testing.
QUIC_EXPORT_PRIVATE quiche::QuicheOptional<quic::QuicWallTime> ParseDerTime(
unsigned tag,
quiche::QuicheStringPiece payload);
} // namespace quic
#endif // QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_