File: pkcs12_reader.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (205 lines) | stat: -rw-r--r-- 7,542 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_ASH_COMPONENTS_KCER_HELPERS_PKCS12_READER_H_
#define CHROMEOS_ASH_COMPONENTS_KCER_HELPERS_PKCS12_READER_H_

#include <nss/certt.h>
#include <stdint.h>

#include <string>
#include <vector>

#include "base/component_export.h"
#include "base/containers/span.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "chromeos/ash/components/kcer/kcer.h"
#include "net/cert/x509_certificate.h"
#include "third_party/boringssl/src/include/openssl/base.h"
#include "third_party/boringssl/src/include/openssl/pkcs7.h"
#include "third_party/boringssl/src/include/openssl/stack.h"
#include "third_party/boringssl/src/include/openssl/x509.h"

namespace kcer::internal {

// Used for logging, the values should never be reordered or reused.
// TODO(miersh): Merge this into kcer::Error.
enum class Pkcs12ReaderStatusCode {
  kSuccess = 0,
  kCreateKeyFailed = 1,
  kCertificateDataMissed = 2,
  kCreateCertFailed = 3,
  kKeyDataMissed = 4,
  kKeyExtractionFailed = 5,
  kChapsSessionMissed = 6,
  kPkcs12CertDerMissed = 7,
  kPkcs12CertDerFailed = 8,
  kPkcs12CertIssuerNameMissed = 9,
  kPkcs12CertIssuerDerNameFailed = 10,
  kPkcs12CertSubjectNameMissed = 11,
  kPkcs12CertSubjectNameDerFailed = 12,
  kPkcs12CertSerialNumberMissed = 13,
  kPkcs12CertSerialNumberDerFailed = 14,
  kKeyAttrDataMissing = 15,
  kFailureDuringCertImport = 16,
  kFailedToParsePkcs12Data = 17,
  kMissedPkcs12Data = 18,
  kPkcs12LabelCreationFailed = 19,
  kPkcs12FindCertsWithSubjectFailed = 20,
  kPkcs12NoValidCertificatesFound = 21,
  kPkcs12NoNicknamesWasExtracted = 22,
  kPkcs12ReachedMaxAttemptForUniqueness = 23,
  kPkcs12MissedNickname = 24,
  kMissedSlotInfo = 25,
  kPkcs12NotSupportedKeyType = 26,
  kPkcs12CNExtractionFailed = 27,
  kEcKeyExtractionFailed = 28,
  kRsaCkaIdExtractionFailed = 29,
  kPKeyExtractionFailed = 30,
  kRsaKeyExtractionFailed = 31,
  kPkcs12RsaModulusEmpty = 32,
  kEcKeyBytesEmpty = 33,
  kEcCkaIdExtractionFailed = 34,
  kPkeyComparisonFailure = 35,
  kPkcs12WrongPassword = 36,
  kPkcs12InvalidMac = 37,
  kPkcs12InvalidFile = 38,
  kPkcs12UnsupportedFile = 39,
  kAlreadyExists = 40,
};

enum class Pkcs12ReaderCertSearchType {
  kDerType,
  kPlainType,
};

struct COMPONENT_EXPORT(KCER) CertData {
  CertData();
  CertData(CertData&& other);
  ~CertData();
  bssl::UniquePtr<X509> x509;
  std::string nickname;
  CertDer cert_der;
};

struct COMPONENT_EXPORT(KCER) KeyData {
  KeyData();
  KeyData(KeyData&&);
  KeyData& operator=(KeyData&&) = default;
  ~KeyData();
  bssl::UniquePtr<EVP_PKEY> key;
  std::vector<uint8_t> cka_id_value;
};

// A helper for std::unique_ptr to call X509_free.
struct X509Deleter {
  void operator()(X509* cert) { X509_free(cert); }
};
using ScopedX509 = std::unique_ptr<X509, X509Deleter>;

// Helper class for working with boringssl and related objects.
// TODO(miersh): Rename, don't mention PKCS#12.
class COMPONENT_EXPORT(KCER) Pkcs12Reader {
 public:
  Pkcs12Reader();

  virtual ~Pkcs12Reader() = default;

  // Populates key and certificates (`key`, `certs`) from the PKCS#12 object
  // `pkcs12_data` protected by the `password`. Returns status code.
  virtual Pkcs12ReaderStatusCode GetPkcs12KeyAndCerts(
      const std::vector<uint8_t>& pkcs12_data,
      const std::string& password,
      bssl::UniquePtr<EVP_PKEY>& key,
      bssl::UniquePtr<STACK_OF(X509)>& certs) const;

  // Populates der encoded certificate and its size (`cert_der`,
  // `cert_der_size`) from X509 (`cert`). Returns status code.
  virtual Pkcs12ReaderStatusCode GetDerEncodedCert(
      X509* cert,
      bssl::UniquePtr<uint8_t>& cert_der,
      int& cert_der_size) const;

  // Populates der encoded issuer name and its size (`issuer_name_data`) from
  // X509 (`cert`). `issuer_name_data` remains valid only as long as the cert is
  // alive because it is only referencing data. Returns status code.
  virtual Pkcs12ReaderStatusCode GetIssuerNameDer(
      X509* cert,
      base::span<const uint8_t>& issuer_name_data) const;

  // Populates der encoded subject name and its size (`subject_name_data`) from
  // X509 (`cert`). `subject_name_data` remains valid only as long as the cert
  // is alive because it is only referencing data. Returns status code.
  virtual Pkcs12ReaderStatusCode GetSubjectNameDer(
      X509* cert,
      base::span<const uint8_t>& subject_name_data) const;

  // Populates der encoded serial number and its size (`serial_number_der`,
  // `serial_number_der_size`) from X509 (`cert`). Returns status code.
  virtual Pkcs12ReaderStatusCode GetSerialNumberDer(
      X509* cert,
      bssl::UniquePtr<uint8_t>& serial_number_der,
      int& serial_number_der_size) const;

  // Populates label (`label`) from X509 (`cert`). Returns status code.
  virtual Pkcs12ReaderStatusCode GetLabel(X509* cert, std::string& label) const;

  // Converts BIGNUM (`bignum`) to bytes.
  virtual std::vector<uint8_t> BignumToBytes(const BIGNUM* bignum) const;

  // Fetches X509 certificates (`found_certs`) with required Subject name
  // (`required_subject_name`) from the provided slot (`slot`).
  // Returns status code.
  virtual Pkcs12ReaderStatusCode FindRawCertsWithSubject(
      PK11SlotInfo* slot,
      base::span<const uint8_t> required_subject_name,
      CERTCertificateList** found_certs) const;

  // Check if there are certificates with the same nickname (`nickname_in`) is
  // present in any PK11 slots. Set (`is_nickname_present`) to true or false.
  // Returns status code.
  virtual Pkcs12ReaderStatusCode IsCertWithNicknameInSlots(
      const std::string& nickname_in,
      bool& is_nickname_present) const;

  // Search if private key is already present in slot (`slot`) using
  // related X509 certificate (`cert`) and certificates type (`cert_type`).
  // Returns Pkcs12ReaderStatusCode::kSuccess
  // if key found, Pkcs12ReaderStatusCode::kKeyDataMissed if key is missed or
  // a status code.
  virtual Pkcs12ReaderStatusCode DoesKeyForCertExist(
      PK11SlotInfo* slot,
      const Pkcs12ReaderCertSearchType cert_type,
      const scoped_refptr<net::X509Certificate>& cert) const;

  // Calculates additional data which can be used for checking key to
  // certificate relation from (`key`). For RSA key it will be modulus. Returns
  // status code.
  virtual Pkcs12ReaderStatusCode EnrichKeyData(KeyData& key_data) const;

  // Check if certificate (`cert`) is related to private key which was used for
  // the calculation of key_data (`key_data`), sets boolean (`is_related`).
  // Returns status code.
  virtual Pkcs12ReaderStatusCode CheckRelation(const KeyData& key_data,
                                               X509* cert,
                                               bool& is_related) const;
  // Converts certificates data from DER representation (`der_cert_data`) and
  // (`der_cert_len`) to X509 (`x509`).
  // Returns status code.
  virtual Pkcs12ReaderStatusCode GetCertFromDerData(
      const unsigned char* der_cert_data,
      int der_cert_len,
      bssl::UniquePtr<X509>& x509) const;

  // Check if certificate (`cert`) is present in specific 'slot'.
  // Returns status code.
  virtual Pkcs12ReaderStatusCode IsCertInSlot(
      PK11SlotInfo* slot,
      const scoped_refptr<net::X509Certificate>& cert,
      bool& is_cert_present) const;
};
}  // namespace kcer::internal

#endif  // CHROMEOS_ASH_COMPONENTS_KCER_HELPERS_PKCS12_READER_H_