1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard
5*3f982cf4SFabien Sanglard #include "util/crypto/pem_helpers.h"
6*3f982cf4SFabien Sanglard
7*3f982cf4SFabien Sanglard #include <openssl/bytestring.h>
8*3f982cf4SFabien Sanglard #include <openssl/pem.h>
9*3f982cf4SFabien Sanglard #include <openssl/rsa.h>
10*3f982cf4SFabien Sanglard #include <stdio.h>
11*3f982cf4SFabien Sanglard #include <string.h>
12*3f982cf4SFabien Sanglard
13*3f982cf4SFabien Sanglard #include "absl/strings/match.h"
14*3f982cf4SFabien Sanglard #include "util/osp_logging.h"
15*3f982cf4SFabien Sanglard
16*3f982cf4SFabien Sanglard namespace openscreen {
17*3f982cf4SFabien Sanglard
ReadCertificatesFromPemFile(absl::string_view filename)18*3f982cf4SFabien Sanglard std::vector<std::string> ReadCertificatesFromPemFile(
19*3f982cf4SFabien Sanglard absl::string_view filename) {
20*3f982cf4SFabien Sanglard FILE* fp = fopen(filename.data(), "r");
21*3f982cf4SFabien Sanglard if (!fp) {
22*3f982cf4SFabien Sanglard return {};
23*3f982cf4SFabien Sanglard }
24*3f982cf4SFabien Sanglard std::vector<std::string> certs;
25*3f982cf4SFabien Sanglard char* name;
26*3f982cf4SFabien Sanglard char* header;
27*3f982cf4SFabien Sanglard unsigned char* data;
28*3f982cf4SFabien Sanglard long length; // NOLINT
29*3f982cf4SFabien Sanglard while (PEM_read(fp, &name, &header, &data, &length) == 1) {
30*3f982cf4SFabien Sanglard if (absl::StartsWith(name, "CERTIFICATE")) {
31*3f982cf4SFabien Sanglard certs.emplace_back(reinterpret_cast<char*>(data), length);
32*3f982cf4SFabien Sanglard }
33*3f982cf4SFabien Sanglard OPENSSL_free(name);
34*3f982cf4SFabien Sanglard OPENSSL_free(header);
35*3f982cf4SFabien Sanglard OPENSSL_free(data);
36*3f982cf4SFabien Sanglard }
37*3f982cf4SFabien Sanglard fclose(fp);
38*3f982cf4SFabien Sanglard return certs;
39*3f982cf4SFabien Sanglard }
40*3f982cf4SFabien Sanglard
ReadKeyFromPemFile(absl::string_view filename)41*3f982cf4SFabien Sanglard bssl::UniquePtr<EVP_PKEY> ReadKeyFromPemFile(absl::string_view filename) {
42*3f982cf4SFabien Sanglard FILE* fp = fopen(filename.data(), "r");
43*3f982cf4SFabien Sanglard if (!fp) {
44*3f982cf4SFabien Sanglard return nullptr;
45*3f982cf4SFabien Sanglard }
46*3f982cf4SFabien Sanglard bssl::UniquePtr<EVP_PKEY> pkey;
47*3f982cf4SFabien Sanglard char* name;
48*3f982cf4SFabien Sanglard char* header;
49*3f982cf4SFabien Sanglard unsigned char* data;
50*3f982cf4SFabien Sanglard long length; // NOLINT
51*3f982cf4SFabien Sanglard while (PEM_read(fp, &name, &header, &data, &length) == 1) {
52*3f982cf4SFabien Sanglard if (absl::StartsWith(name, "RSA PRIVATE KEY")) {
53*3f982cf4SFabien Sanglard OSP_DCHECK(!pkey);
54*3f982cf4SFabien Sanglard CBS cbs;
55*3f982cf4SFabien Sanglard CBS_init(&cbs, data, length);
56*3f982cf4SFabien Sanglard RSA* rsa = RSA_parse_private_key(&cbs);
57*3f982cf4SFabien Sanglard if (rsa) {
58*3f982cf4SFabien Sanglard pkey.reset(EVP_PKEY_new());
59*3f982cf4SFabien Sanglard EVP_PKEY_assign_RSA(pkey.get(), rsa);
60*3f982cf4SFabien Sanglard }
61*3f982cf4SFabien Sanglard }
62*3f982cf4SFabien Sanglard OPENSSL_free(name);
63*3f982cf4SFabien Sanglard OPENSSL_free(header);
64*3f982cf4SFabien Sanglard OPENSSL_free(data);
65*3f982cf4SFabien Sanglard }
66*3f982cf4SFabien Sanglard fclose(fp);
67*3f982cf4SFabien Sanglard return pkey;
68*3f982cf4SFabien Sanglard }
69*3f982cf4SFabien Sanglard
70*3f982cf4SFabien Sanglard } // namespace openscreen
71