ca-certificates.crt解析加载到nssdb中

2023-12-16 07:04

本文主要是介绍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中的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/499570

相关文章

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Python利用ElementTree实现快速解析XML文件

《Python利用ElementTree实现快速解析XML文件》ElementTree是Python标准库的一部分,而且是Python标准库中用于解析和操作XML数据的模块,下面小编就来和大家详细讲讲... 目录一、XML文件解析到底有多重要二、ElementTree快速入门1. 加载XML的两种方式2.

Java的栈与队列实现代码解析

《Java的栈与队列实现代码解析》栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶,栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等,本文给大家介绍J... 目录栈的概念(Stack)栈的实现代码队列(Queue)模拟实现队列(双链表实现)循环队列(循环数组

java解析jwt中的payload的用法

《java解析jwt中的payload的用法》:本文主要介绍java解析jwt中的payload的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java解析jwt中的payload1. 使用 jjwt 库步骤 1:添加依赖步骤 2:解析 JWT2. 使用 N

Python中__init__方法使用的深度解析

《Python中__init__方法使用的深度解析》在Python的面向对象编程(OOP)体系中,__init__方法如同建造房屋时的奠基仪式——它定义了对象诞生时的初始状态,下面我们就来深入了解下_... 目录一、__init__的基因图谱二、初始化过程的魔法时刻继承链中的初始化顺序self参数的奥秘默认

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Java字符串处理全解析(String、StringBuilder与StringBuffer)

《Java字符串处理全解析(String、StringBuilder与StringBuffer)》:本文主要介绍Java字符串处理全解析(String、StringBuilder与StringBu... 目录Java字符串处理全解析:String、StringBuilder与StringBuffer一、St

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

C#中async await异步关键字用法和异步的底层原理全解析

《C#中asyncawait异步关键字用法和异步的底层原理全解析》:本文主要介绍C#中asyncawait异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录C#异步编程一、异步编程基础二、异步方法的工作原理三、代码示例四、编译后的底层实现五、总结C#异步编程