• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 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 #include "util/crypto/pem_helpers.h"
6 
7 #include <openssl/bytestring.h>
8 #include <openssl/pem.h>
9 #include <openssl/rsa.h>
10 #include <stdio.h>
11 #include <string.h>
12 
13 #include "absl/strings/match.h"
14 #include "util/osp_logging.h"
15 
16 namespace openscreen {
17 
ReadCertificatesFromPemFile(absl::string_view filename)18 std::vector<std::string> ReadCertificatesFromPemFile(
19     absl::string_view filename) {
20   FILE* fp = fopen(filename.data(), "r");
21   if (!fp) {
22     return {};
23   }
24   std::vector<std::string> certs;
25   char* name;
26   char* header;
27   unsigned char* data;
28   long length;  // NOLINT
29   while (PEM_read(fp, &name, &header, &data, &length) == 1) {
30     if (absl::StartsWith(name, "CERTIFICATE")) {
31       certs.emplace_back(reinterpret_cast<char*>(data), length);
32     }
33     OPENSSL_free(name);
34     OPENSSL_free(header);
35     OPENSSL_free(data);
36   }
37   fclose(fp);
38   return certs;
39 }
40 
ReadKeyFromPemFile(absl::string_view filename)41 bssl::UniquePtr<EVP_PKEY> ReadKeyFromPemFile(absl::string_view filename) {
42   FILE* fp = fopen(filename.data(), "r");
43   if (!fp) {
44     return nullptr;
45   }
46   bssl::UniquePtr<EVP_PKEY> pkey;
47   char* name;
48   char* header;
49   unsigned char* data;
50   long length;  // NOLINT
51   while (PEM_read(fp, &name, &header, &data, &length) == 1) {
52     if (absl::StartsWith(name, "RSA PRIVATE KEY")) {
53       OSP_DCHECK(!pkey);
54       CBS cbs;
55       CBS_init(&cbs, data, length);
56       RSA* rsa = RSA_parse_private_key(&cbs);
57       if (rsa) {
58         pkey.reset(EVP_PKEY_new());
59         EVP_PKEY_assign_RSA(pkey.get(), rsa);
60       }
61     }
62     OPENSSL_free(name);
63     OPENSSL_free(header);
64     OPENSSL_free(data);
65   }
66   fclose(fp);
67   return pkey;
68 }
69 
70 }  // namespace openscreen
71