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#ifndef NET_CERT_X509_UTIL_H_
6#define NET_CERT_X509_UTIL_H_
7
8#include <stdint.h>
9
10#include <memory>
11#include <string>
12#include <vector>
13
14#include "base/containers/span.h"
15#include "base/macros.h"
16#include "base/memory/ref_counted.h"
17#include "base/strings/string_piece.h"
18#include "base/time/time.h"
19#include "crypto/signature_verifier.h"
20#include "net/base/hash_value.h"
21#include "net/base/net_export.h"
22#include "third_party/boringssl/src/include/openssl/base.h"
23#include "third_party/boringssl/src/include/openssl/pool.h"
24
25namespace crypto {
26class RSAPrivateKey;
27}
28
29namespace net {
30
31struct ParseCertificateOptions;
32class X509Certificate;
33
34namespace x509_util {
35
36// Supported digest algorithms for signing certificates.
37enum DigestAlgorithm { DIGEST_SHA256 };
38
39// Generate a 'tls-server-end-point' channel binding based on the specified
40// certificate. Channel bindings are based on RFC 5929.
41NET_EXPORT_PRIVATE bool GetTLSServerEndPointChannelBinding(
42 const X509Certificate& certificate,
43 std::string* token);
44
45// Creates a public-private keypair and a self-signed certificate.
46// Subject, serial number and validity period are given as parameters.
47// The certificate is signed by the private key in |key|. The key length and
48// signature algorithm may be updated periodically to match best practices.
49//
50// |subject| is a distinguished name defined in RFC4514 with _only_ a CN
51// component, as in:
52// CN=Michael Wong
53//
54// SECURITY WARNING
55//
56// Using self-signed certificates has the following security risks:
57// 1. Encryption without authentication and thus vulnerable to
58// man-in-the-middle attacks.
59// 2. Self-signed certificates cannot be revoked.
60//
61// Use this certificate only after the above risks are acknowledged.
62NET_EXPORT bool CreateKeyAndSelfSignedCert(
63 const std::string& subject,
64 uint32_t serial_number,
65 base::Time not_valid_before,
66 base::Time not_valid_after,
67 std::unique_ptr<crypto::RSAPrivateKey>* key,
68 std::string* der_cert);
69
70struct NET_EXPORT Extension {
71 Extension(base::span<const uint8_t> oid,
72 bool critical,
73 base::span<const uint8_t> contents);
74 ~Extension();
75 Extension(const Extension&);
76
77 base::span<const uint8_t> oid;
78 bool critical;
79 base::span<const uint8_t> contents;
80};
81
82// Creates a self-signed certificate from a provided key, using the specified
83// hash algorithm.
84NET_EXPORT bool CreateSelfSignedCert(
85 EVP_PKEY* key,
86 DigestAlgorithm alg,
87 const std::string& subject,
88 uint32_t serial_number,
89 base::Time not_valid_before,
90 base::Time not_valid_after,
91 const std::vector<Extension>& extension_specs,
92 std::string* der_cert);
93
94// Returns a CRYPTO_BUFFER_POOL for deduplicating certificates.
95NET_EXPORT CRYPTO_BUFFER_POOL* GetBufferPool();
96
97// Creates a CRYPTO_BUFFER in the same pool returned by GetBufferPool.
98NET_EXPORT bssl::UniquePtr<CRYPTO_BUFFER> CreateCryptoBuffer(
99 const uint8_t* data,
100 size_t length);
101
102// Creates a CRYPTO_BUFFER in the same pool returned by GetBufferPool.
103NET_EXPORT bssl::UniquePtr<CRYPTO_BUFFER> CreateCryptoBuffer(
104 const base::StringPiece& data);
105
106// Overload with no definition, to disallow creating a CRYPTO_BUFFER from a
107// char* due to StringPiece implicit ctor.
108NET_EXPORT bssl::UniquePtr<CRYPTO_BUFFER> CreateCryptoBuffer(
109 const char* invalid_data);
110
111// Compares two CRYPTO_BUFFERs and returns true if they have the same contents.
112NET_EXPORT bool CryptoBufferEqual(const CRYPTO_BUFFER* a,
113 const CRYPTO_BUFFER* b);
114
115// Returns a StringPiece pointing to the data in |buffer|.
116NET_EXPORT base::StringPiece CryptoBufferAsStringPiece(
117 const CRYPTO_BUFFER* buffer);
118
119// Creates a new X509Certificate from the chain in |buffers|, which must have at
120// least one element.
121NET_EXPORT scoped_refptr<X509Certificate> CreateX509CertificateFromBuffers(
122 const STACK_OF(CRYPTO_BUFFER) * buffers);
123
124// Returns the default ParseCertificateOptions for the net stack.
125NET_EXPORT ParseCertificateOptions DefaultParseCertificateOptions();
126
127// On success, returns true and updates |hash| to be the SHA-256 hash of the
128// subjectPublicKeyInfo of the certificate in |buffer|. If |buffer| is not a
129// valid certificate, returns false and |hash| is in an undefined state.
130NET_EXPORT bool CalculateSha256SpkiHash(const CRYPTO_BUFFER* buffer,
131 HashValue* hash) WARN_UNUSED_RESULT;
132
133// Calls |verifier->VerifyInit|, using the public key from |certificate|,
134// checking if the digitalSignature key usage bit is present, and returns true
135// on success or false on error.
136NET_EXPORT bool SignatureVerifierInitWithCertificate(
137 crypto::SignatureVerifier* verifier,
138 crypto::SignatureVerifier::SignatureAlgorithm signature_algorithm,
139 base::span<const uint8_t> signature,
140 const CRYPTO_BUFFER* certificate);
141
142} // namespace x509_util
143
144} // namespace net
145
146#endif // NET_CERT_X509_UTIL_H_
147