本文主要是介绍ca-certificates.crt解析加载到nssdb中,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
openssl crl2pkcs7 -nocrl -certfile /etc/ssl/certs/ca-certificates.crt | openssl pkcs7 -print_certs -noout -text
ca-certificates.crt为操作系统根证书列表。
获取证书以后使用PK11_ImportDERCert将证书导入到nssdb中
base::FilePath cert_path = base::FilePath("/etc/ssl/certs/ca-certificates.crt");std::string cert_data;if (base::ReadFileToString(cert_path, &cert_data)){base::span<const uint8_t> datas = base::as_bytes(base::make_span(cert_data));base::StringPiece data_string(reinterpret_cast<const char*>(datas.data()),datas.size());std::vector<std::string> pem_headers;// To maintain compatibility with NSS/Firefox, CERTIFICATE is a universally// valid PEM block header for any format.pem_headers.push_back(kCertificateHeader);pem_headers.push_back(kPKCS7Header);PEMTokenizer pem_tokenizer(data_string, pem_headers);int i = 0;while (pem_tokenizer.GetNext()) {std::string decoded(pem_tokenizer.data());LOG(INFO)<<decoded;SECItem certData;certData.data = reinterpret_cast<unsigned char*>(const_cast<char*>(decoded.c_str()));certData.len = decoded.size();certData.type = siDERCertBuffer;std::string name = "cert"+std::to_string(i);std::string fileName = "/home/arv000/Desktop/cc/"+name;std::ofstream outFile(fileName);if (outFile.is_open()) {// 写入字符串到文件outFile << decoded;// 关闭文件流outFile.close();}SECStatus status = PK11_ImportDERCert(slot, &certData, CK_INVALID_HANDLE ,const_cast<char*>(name.c_str()) /* is_perm */, PR_TRUE /* copyDER */);i++;}}
// Copyright (c) 2010 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.#include "crypto/cert/pem.h"#include "base/base64.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"namespace {const char kPEMSearchBlock[] = "-----BEGIN ";
const char kPEMBeginBlock[] = "-----BEGIN %s-----";
const char kPEMEndBlock[] = "-----END %s-----";} // namespacenamespace crypto {using base::StringPiece;struct PEMTokenizer::PEMType {std::string type;std::string header;std::string footer;
};PEMTokenizer::PEMTokenizer(const StringPiece& str,const std::vector<std::string>& allowed_block_types) {Init(str, allowed_block_types);
}PEMTokenizer::~PEMTokenizer() = default;bool PEMTokenizer::GetNext() {while (pos_ != StringPiece::npos) {// Scan for the beginning of the next PEM encoded block.pos_ = str_.find(kPEMSearchBlock, pos_);if (pos_ == StringPiece::npos)return false; // No more PEM blocksstd::vector<PEMType>::const_iterator it;// Check to see if it is of an acceptable block type.for (it = block_types_.begin(); it != block_types_.end(); ++it) {if (!base::StartsWith(str_.substr(pos_), it->header))continue;// Look for a footer matching the header. If none is found, then all// data following this point is invalid and should not be parsed.StringPiece::size_type footer_pos = str_.find(it->footer, pos_);if (footer_pos == StringPiece::npos) {pos_ = StringPiece::npos;return false;}// Chop off the header and footer and parse the data in between.StringPiece::size_type data_begin = pos_ + it->header.size();pos_ = footer_pos + it->footer.size();block_type_ = it->type;StringPiece encoded = str_.substr(data_begin, footer_pos - data_begin);if (!base::Base64Decode(base::CollapseWhitespaceASCII(encoded, true),&data_)) {// The most likely cause for a decode failure is a datatype that// includes PEM headers, which are not supported.break;}return true;}// If the block did not match any acceptable type, move past it and// continue the search. Otherwise, |pos_| has been updated to the most// appropriate search position to continue searching from and should not// be adjusted.if (it == block_types_.end())pos_ += sizeof(kPEMSearchBlock);}return false;
}void PEMTokenizer::Init(const StringPiece& str,const std::vector<std::string>& allowed_block_types) {str_ = str;pos_ = 0;// Construct PEM header/footer strings for all the accepted types, to// reduce parsing later.for (auto it = allowed_block_types.begin(); it != allowed_block_types.end();++it) {PEMType allowed_type;allowed_type.type = *it;allowed_type.header = base::StringPrintf(kPEMBeginBlock, it->c_str());allowed_type.footer = base::StringPrintf(kPEMEndBlock, it->c_str());block_types_.push_back(allowed_type);}
}std::string PEMEncode(base::StringPiece data, const std::string& type) {std::string b64_encoded;base::Base64Encode(data, &b64_encoded);// Divide the Base-64 encoded data into 64-character chunks, as per// 4.3.2.4 of RFC 1421.static const size_t kChunkSize = 64;size_t chunks = (b64_encoded.size() + (kChunkSize - 1)) / kChunkSize;std::string pem_encoded;pem_encoded.reserve(// header & footer17 + 15 + type.size() * 2 +// encoded datab64_encoded.size() +// newline characters for line wrapping in encoded datachunks);pem_encoded = "-----BEGIN ";pem_encoded.append(type);pem_encoded.append("-----\n");for (size_t i = 0, chunk_offset = 0; i < chunks;++i, chunk_offset += kChunkSize) {pem_encoded.append(b64_encoded, chunk_offset, kChunkSize);pem_encoded.append("\n");}pem_encoded.append("-----END ");pem_encoded.append(type);pem_encoded.append("-----\n");return pem_encoded;
}} // namespace net
// Copyright (c) 2011 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 NET_CERT_PEM_H_
#define NET_CERT_PEM_H_#include <stddef.h>#include <string>
#include <vector>#include "base/macros.h"
#include "base/strings/string_piece.h"namespace crypto {// PEMTokenizer is a utility class for the parsing of data encapsulated
// using RFC 1421, Privacy Enhancement for Internet Electronic Mail. It
// does not implement the full specification, most notably it does not
// support the Encapsulated Header Portion described in Section 4.4.
class PEMTokenizer {public:// Create a new PEMTokenizer that iterates through |str| searching for// instances of PEM encoded blocks that are of the |allowed_block_types|.// |str| must remain valid for the duration of the PEMTokenizer.PEMTokenizer(const base::StringPiece& str,const std::vector<std::string>& allowed_block_types);~PEMTokenizer();// Attempts to decode the next PEM block in the string. Returns false if no// PEM blocks can be decoded. The decoded PEM block will be available via// data().bool GetNext();// Returns the PEM block type (eg: CERTIFICATE) of the last successfully// decoded PEM block.// GetNext() must have returned true before calling this method.const std::string& block_type() const { return block_type_; }// Returns the raw, Base64-decoded data of the last successfully decoded// PEM block.// GetNext() must have returned true before calling this method.const std::string& data() const { return data_; }private:void Init(const base::StringPiece& str,const std::vector<std::string>& allowed_block_types);// A simple cache of the allowed PEM header and footer for a given PEM// block type, so that it is only computed once.struct PEMType;// The string to search, which must remain valid for as long as this class// is around.base::StringPiece str_;// The current position within |str_| that searching should begin from,// or StringPiece::npos if iteration is completebase::StringPiece::size_type pos_;// The type of data that was encoded, as indicated in the PEM// Pre-Encapsulation Boundary (eg: CERTIFICATE, PKCS7, or// PRIVACY-ENHANCED MESSAGE).std::string block_type_;// The types of PEM blocks that are allowed. PEM blocks that are not of// one of these types will be skipped.std::vector<PEMType> block_types_;// The raw (Base64-decoded) data of the last successfully decoded block.std::string data_;DISALLOW_COPY_AND_ASSIGN(PEMTokenizer);
};// Encodes |data| in the encapsulated message format described in RFC 1421,
// with |type| as the PEM block type (eg: CERTIFICATE).std::string PEMEncode(base::StringPiece data,const std::string& type);} // namespace net#endif // NET_CERT_PEM_H_
这篇关于ca-certificates.crt解析加载到nssdb中的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!