Last active
November 29, 2020 10:17
-
-
Save trueroad/40072532a258b3519c8f6beabe829b0c to your computer and use it in GitHub Desktop.
Time stamp (RFC 3161) tools
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- From RFC 2630 / 3369 / 3852 / 5652 -- | |
CryptographicMessageSyntax2004 | |
{ iso(1) member-body(2) us(840) rsadsi(113549) | |
pkcs(1) pkcs-9(9) smime(16) modules(0) cms-2004(24) } | |
DEFINITIONS IMPLICIT TAGS ::= | |
BEGIN | |
-- ... -- | |
-- Cryptographic Message Syntax | |
ContentInfo ::= SEQUENCE { | |
contentType ContentType, | |
content [0] EXPLICIT ANY DEFINED BY contentType } | |
ContentType ::= OBJECT IDENTIFIER | |
SignedData ::= SEQUENCE { | |
version CMSVersion, | |
digestAlgorithms DigestAlgorithmIdentifiers, | |
encapContentInfo EncapsulatedContentInfo, | |
certificates [0] IMPLICIT CertificateSet OPTIONAL, | |
crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, | |
signerInfos SignerInfos } | |
DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier | |
SignerInfos ::= SET OF SignerInfo | |
EncapsulatedContentInfo ::= SEQUENCE { | |
eContentType ContentType, | |
eContent [0] EXPLICIT OCTET STRING OPTIONAL } | |
SignerInfo ::= SEQUENCE { | |
version CMSVersion, | |
sid SignerIdentifier, | |
digestAlgorithm DigestAlgorithmIdentifier, | |
signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, | |
signatureAlgorithm SignatureAlgorithmIdentifier, | |
signature SignatureValue, | |
unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL } | |
SignerIdentifier ::= CHOICE { | |
issuerAndSerialNumber IssuerAndSerialNumber, | |
subjectKeyIdentifier [0] SubjectKeyIdentifier } | |
SignedAttributes ::= SET SIZE (1..MAX) OF Attribute | |
UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute | |
Attribute ::= SEQUENCE { | |
attrType OBJECT IDENTIFIER, | |
attrValues SET OF AttributeValue } | |
AttributeValue ::= ANY | |
SignatureValue ::= OCTET STRING | |
-- ... -- | |
SubjectKeyIdentifier ::= OCTET STRING | |
-- ... -- | |
DigestAlgorithmIdentifier ::= AlgorithmIdentifier | |
SignatureAlgorithmIdentifier ::= AlgorithmIdentifier | |
-- ... -- | |
CMSVersion ::= INTEGER { v0(0), v1(1), v2(2), v3(3), v4(4), v5(5) } | |
-- ... -- | |
-- From RFC 2459 / 3280 / 5280 -- | |
-- ... -- | |
AlgorithmIdentifier ::= SEQUENCE { | |
algorithm OBJECT IDENTIFIER, | |
parameters ANY DEFINED BY algorithm OPTIONAL } | |
-- contains a value of the type | |
-- registered for use with the | |
-- algorithm object identifier value | |
-- ... -- | |
-- dummy -- | |
-- RFC 5652 | |
RevocationInfoChoices ::= SET OF ANY | |
CertificateSet ::= SET OF ANY | |
IssuerAndSerialNumber ::= SEQUENCE OF ANY | |
END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if HAVE_CONFIG_H | |
# include "config.h" | |
#endif | |
#include <libtasn1.h> | |
const asn1_static_node cms_asn1_tab[] = { | |
{ "CryptographicMessageSyntax2004", 536875024, NULL }, | |
{ NULL, 1610612748, NULL }, | |
{ "iso", 1073741825, "1"}, | |
{ "member-body", 1073741825, "2"}, | |
{ "us", 1073741825, "840"}, | |
{ "rsadsi", 1073741825, "113549"}, | |
{ "pkcs", 1073741825, "1"}, | |
{ "pkcs-9", 1073741825, "9"}, | |
{ "smime", 1073741825, "16"}, | |
{ "modules", 1073741825, "0"}, | |
{ "cms-2004", 1, "24"}, | |
{ "ContentInfo", 1610612741, NULL }, | |
{ "contentType", 1073741826, "ContentType"}, | |
{ "content", 541073421, NULL }, | |
{ NULL, 1073743880, "0"}, | |
{ "contentType", 1, NULL }, | |
{ "ContentType", 1073741836, NULL }, | |
{ "SignedData", 1610612741, NULL }, | |
{ "version", 1073741826, "CMSVersion"}, | |
{ "digestAlgorithms", 1073741826, "DigestAlgorithmIdentifiers"}, | |
{ "encapContentInfo", 1073741826, "EncapsulatedContentInfo"}, | |
{ "certificates", 1610637314, "CertificateSet"}, | |
{ NULL, 4104, "0"}, | |
{ "crls", 1610637314, "RevocationInfoChoices"}, | |
{ NULL, 4104, "1"}, | |
{ "signerInfos", 2, "SignerInfos"}, | |
{ "DigestAlgorithmIdentifiers", 1610612751, NULL }, | |
{ NULL, 2, "DigestAlgorithmIdentifier"}, | |
{ "SignerInfos", 1610612751, NULL }, | |
{ NULL, 2, "SignerInfo"}, | |
{ "EncapsulatedContentInfo", 1610612741, NULL }, | |
{ "eContentType", 1073741826, "ContentType"}, | |
{ "eContent", 536895495, NULL }, | |
{ NULL, 2056, "0"}, | |
{ "SignerInfo", 1610612741, NULL }, | |
{ "version", 1073741826, "CMSVersion"}, | |
{ "sid", 1073741826, "SignerIdentifier"}, | |
{ "digestAlgorithm", 1073741826, "DigestAlgorithmIdentifier"}, | |
{ "signedAttrs", 1610637314, "SignedAttributes"}, | |
{ NULL, 4104, "0"}, | |
{ "signatureAlgorithm", 1073741826, "SignatureAlgorithmIdentifier"}, | |
{ "signature", 1073741826, "SignatureValue"}, | |
{ "unsignedAttrs", 536895490, "UnsignedAttributes"}, | |
{ NULL, 4104, "1"}, | |
{ "SignerIdentifier", 1610612754, NULL }, | |
{ "issuerAndSerialNumber", 1073741826, "IssuerAndSerialNumber"}, | |
{ "subjectKeyIdentifier", 536879106, "SubjectKeyIdentifier"}, | |
{ NULL, 4104, "0"}, | |
{ "SignedAttributes", 1612709903, NULL }, | |
{ "MAX", 1074266122, "1"}, | |
{ NULL, 2, "Attribute"}, | |
{ "UnsignedAttributes", 1612709903, NULL }, | |
{ "MAX", 1074266122, "1"}, | |
{ NULL, 2, "Attribute"}, | |
{ "Attribute", 1610612741, NULL }, | |
{ "attrType", 1073741836, NULL }, | |
{ "attrValues", 536870927, NULL }, | |
{ NULL, 2, "AttributeValue"}, | |
{ "AttributeValue", 1073741837, NULL }, | |
{ "SignatureValue", 1073741831, NULL }, | |
{ "SubjectKeyIdentifier", 1073741831, NULL }, | |
{ "DigestAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"}, | |
{ "SignatureAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"}, | |
{ "CMSVersion", 1610874883, NULL }, | |
{ "v0", 1073741825, "0"}, | |
{ "v1", 1073741825, "1"}, | |
{ "v2", 1073741825, "2"}, | |
{ "v3", 1073741825, "3"}, | |
{ "v4", 1073741825, "4"}, | |
{ "v5", 1, "5"}, | |
{ "AlgorithmIdentifier", 1610612741, NULL }, | |
{ "algorithm", 1073741836, NULL }, | |
{ "parameters", 541081613, NULL }, | |
{ "algorithm", 1, NULL }, | |
{ "RevocationInfoChoices", 1610612751, NULL }, | |
{ NULL, 13, NULL }, | |
{ "CertificateSet", 1610612751, NULL }, | |
{ NULL, 13, NULL }, | |
{ "IssuerAndSerialNumber", 536870923, NULL }, | |
{ NULL, 13, NULL }, | |
{ NULL, 0, NULL } | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
BIN_REQ = ts_req | |
OBJS_REQ = ts_req.o tr_libtasn1.o \ | |
tr_hash_gnutls.o tr_gnutls_init.o ts_asn1_tab.o | |
BIN_PKCS7_REQ = pkcs7_ts_req | |
OBJS_PKCS7_REQ = pkcs7_ts_req.o tr_libtasn1.o \ | |
tr_hash_gnutls.o tr_gnutls_init.o \ | |
ts_asn1_tab.o cms_asn1_tab.o | |
BIN_RESP = ts_resp | |
OBJS_RESP = ts_resp.o tr_libtasn1.o tr_hash_gnutls.o \ | |
ts_asn1_tab.o cms_asn1_tab.o | |
BIN_MERGE = merge_sign | |
OBJS_MERGE = merge_sign.o tr_libtasn1.o cms_asn1_tab.o | |
ASN1PARSER = asn1Parser | |
BIN = $(sort $(BIN_REQ) $(BIN_PKCS7_REQ) $(BIN_RESP) $(BIN_MERGE)) | |
OBJS = $(sort $(OBJS_REQ) $(OBJS_PKCS7_REQ) $(OBJS_RESP) $(OBJS_MERGE)) | |
all: $(BIN) ts_asn1_tab.c cms_asn1_tab.c | |
.PHONY: all clean | |
CXXFLAGS += -std=c++11 | |
LDLIBS += -ltasn1 -lgnutls | |
DEPS = $(OBJS:.o=.d) | |
CPPFLAGS += -MMD -MP -MF $(@:.o=.d) -MT $@ | |
-include $(DEPS) | |
$(BIN_REQ): $(OBJS_REQ) | |
$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ | |
$(BIN_PKCS7_REQ): $(OBJS_PKCS7_REQ) | |
$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ | |
$(BIN_RESP): $(OBJS_RESP) | |
$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ | |
$(BIN_MERGE): $(OBJS_MERGE) | |
$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ | |
%_asn1_tab.c: %.asn1 | |
$(ASN1PARSER) -o $@ $^ | |
clean: | |
$(RM) *~ $(OBJS) $(DEPS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Time stamp (RFC 3161) tools | |
// https://gist.github.com/trueroad/40072532a258b3519c8f6beabe829b0c | |
// | |
// merge_sign.cc: | |
// PKCS#7 signed-data merger | |
// | |
// Copyright (C) 2019 Masamichi Hosoda. | |
// All rights reserved. | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions | |
// are met: | |
// | |
// * Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// * Redistributions in binary form must reproduce the above copyright notice, | |
// this list of conditions and the following disclaimer in the documentation | |
// and/or other materials provided with the distribution. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
// ARE DISCLAIMED. | |
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
// SUCH DAMAGE. | |
// | |
#include <fstream> | |
#include <iostream> | |
#include <stdexcept> | |
#include <string> | |
#include <vector> | |
#include "tr_libtasn1.hh" | |
#include "tr_util_binary.hh" | |
extern "C" const asn1_static_node cms_asn1_tab[]; | |
int main (int argc, char *argv[]) | |
{ | |
std::cout | |
<< "PKCS#7 signed-data merger" | |
<< std::endl | |
<< "Copyright (C) 2019 Masamichi Hosoda" | |
<< std::endl << std::endl; | |
if (argc != 4) | |
{ | |
std::cout | |
<< "usage: " << argv[0] | |
<< " (in)MAIN.p7s (in)SUB.p7s (out)MERGED.p7s" | |
<< std::endl; | |
return 1; | |
} | |
std::string filename_main {argv[1]}; | |
std::string filename_sub {argv[2]}; | |
std::string filename_merged {argv[3]}; | |
std::cout | |
<< "main filename: " << filename_main << std::endl | |
<< "sub filename: " << filename_sub << std::endl | |
<< "merged filename: " << filename_merged << std::endl << std::endl; | |
try | |
{ | |
tr_libtasn1::asn1_definition d (cms_asn1_tab); | |
std::cout << "decoding main..." << std::endl; | |
auto s_ci {d.create_element | |
("CryptographicMessageSyntax2004.ContentInfo")}; | |
s_ci.der_decoding (tr_util::fileload_binary (filename_main)); | |
std::cout << "decoding main signed-data..." << std::endl; | |
auto sd {s_ci.read_value_binary ("content")}; | |
auto s_sd {d.create_element | |
("CryptographicMessageSyntax2004.SignedData")}; | |
s_sd.der_decoding (sd); | |
std::cout << "checking signature..." << std::endl; | |
auto signs {s_sd.number_of_elements ("signerInfos")}; | |
if (signs > 1) | |
{ | |
std::cout << "error: There are multiple signatures." << std::endl | |
<< "signerInfos has " << signs | |
<< " elements" << std::endl; | |
return 1; | |
} | |
else if (signs == 0) | |
{ | |
std::cout << "error: There are no signatures." << std::endl | |
<< "signerInfos has no elements" << std::endl; | |
return 1; | |
} | |
std::cout << "appending new signerInfos..." << std::endl; | |
s_sd.write_value ("signerInfos", "NEW", 1); | |
std::cout << "copying signerInfos..." | |
<< std::endl; | |
s_sd.copy_node ("signerInfos.?2.version", | |
"signerInfos.?1.version"); | |
s_sd.copy_node ("signerInfos.?2.sid", | |
"signerInfos.?1.sid"); | |
s_sd.copy_node ("signerInfos.?2.digestAlgorithm", | |
"signerInfos.?1.digestAlgorithm"); | |
{ | |
auto nodes {s_sd.number_of_elements_optional | |
("signerInfos.?1.signedAttrs")}; | |
if (nodes > 0) | |
{ | |
for (int i = 1; i <= nodes; ++i) | |
{ | |
s_sd.write_value ("signerInfos.?2.signedAttrs", "NEW", 1); | |
s_sd.copy_node ("signerInfos.?2.signedAttrs.?" | |
+ std::to_string (i), | |
"signerInfos.?1.signedAttrs.?" | |
+ std::to_string (i)); | |
} | |
} | |
else | |
s_sd.delete_element ("signerInfos.?2.signedAttrs"); | |
} | |
s_sd.copy_node ("signerInfos.?2.signatureAlgorithm", | |
"signerInfos.?1.signatureAlgorithm"); | |
s_sd.copy_node ("signerInfos.?2.signature", | |
"signerInfos.?1.signature"); | |
{ | |
auto nodes {s_sd.number_of_elements_optional | |
("signerInfos.?1.unsignedAttrs")}; | |
if (nodes > 0) | |
{ | |
for (int i = 1; i <= nodes; ++i) | |
{ | |
s_sd.write_value ("signerInfos.?2.unsignedAttrs", "NEW", 1); | |
s_sd.copy_node ("signerInfos.?2.unsignedAttrs.?" | |
+ std::to_string (i), | |
"signerInfos.?1.unsignedAttrs.?" | |
+ std::to_string (i)); | |
} | |
} | |
} | |
std::cout << "adding new unsignedAttrs..." << std::endl; | |
s_sd.write_value ("signerInfos.?2.unsignedAttrs", "NEW", 1); | |
s_sd.write_value ("signerInfos.?2.unsignedAttrs.?LAST.attrType", | |
"1.2.840.113549.1.9.16.2.14"); | |
s_sd.write_value ("signerInfos.?2.unsignedAttrs.?LAST.attrValues", | |
"NEW", 1); | |
s_sd.write_value ("signerInfos.?2.unsignedAttrs.?LAST.attrValues.?1", | |
tr_util::fileload_binary (filename_sub)); | |
std::cout << "deleting old signerInfos..." << std::endl; | |
s_sd.delete_element ("signerInfos.?1"); | |
std::cout << "creating new pkcs7 signed-data..." << std::endl; | |
auto s_ci_merged {d.create_element | |
("CryptographicMessageSyntax2004.ContentInfo")}; | |
s_ci_merged.write_value ("contentType", "1.2.840.113549.1.7.2"); | |
auto sd_der {s_sd.der_coding ("")}; | |
s_ci_merged.write_value ("content", sd_der); | |
std::cout << "coding new pkcs7 signed-data..." << std::endl; | |
auto merged {s_ci_merged.der_coding ("")}; | |
std::cout << "writing file \"" << filename_merged | |
<< "\"..." << std::endl; | |
tr_util::filesave (filename_merged, merged); | |
} | |
catch (std::runtime_error &e) | |
{ | |
std::cout << e.what () << std::endl; | |
return 1; | |
} | |
std::cout << std::endl << "complete" << std::endl; | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Time stamp (RFC 3161) tools | |
// https://gist.github.com/trueroad/40072532a258b3519c8f6beabe829b0c | |
// | |
// pkcs7_ts_req.cc: | |
// Time stamp request generator for PKCS#7 signed-data | |
// | |
// Copyright (C) 2019, 2020 Masamichi Hosoda. | |
// All rights reserved. | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions | |
// are met: | |
// | |
// * Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// * Redistributions in binary form must reproduce the above copyright notice, | |
// this list of conditions and the following disclaimer in the documentation | |
// and/or other materials provided with the distribution. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
// ARE DISCLAIMED. | |
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
// SUCH DAMAGE. | |
// | |
#include <fstream> | |
#include <iostream> | |
#include <stdexcept> | |
#include <string> | |
#include <vector> | |
#include "tr_gnutls_init.hh" | |
#include "tr_util_binary.hh" | |
#include "ts_req_gen_req.hh" | |
extern "C" const asn1_static_node cms_asn1_tab[]; | |
namespace | |
{ | |
std::vector<unsigned char> get_signature_value (const std::string &filename) | |
{ | |
tr_libtasn1::asn1_definition d (cms_asn1_tab); | |
auto s_ci {d.create_element | |
("CryptographicMessageSyntax2004.ContentInfo")}; | |
s_ci.der_decoding (tr_util::fileload_binary (filename)); | |
auto sd {s_ci.read_value_binary ("content")}; | |
auto s_sd {d.create_element ("CryptographicMessageSyntax2004.SignedData")}; | |
s_sd.der_decoding (sd); | |
auto signs {s_sd.number_of_elements ("signerInfos")}; | |
if (signs > 1) | |
{ | |
throw std::runtime_error ("error: There are multiple signatures."); | |
} | |
else if (signs == 0) | |
{ | |
throw std::runtime_error ("error: There are no signatures."); | |
} | |
return s_sd.read_value_binary ("signerInfos.?1.signature"); | |
} | |
} | |
int main (int argc, char *argv[]) | |
{ | |
std::cout | |
<< "Time stamp request (RFC 3161) generator for PKCS#7 signed-data" | |
<< std::endl | |
<< "Copyright (C) 2019, 2020 Masamichi Hosoda" | |
<< std::endl << std::endl; | |
if (argc != 4) | |
{ | |
std::cout | |
<< "usage: " << argv[0] | |
<< " DIGEST (in)TO-BE-SIGNED.p7s (out)TIME-STAMP-REQUEST.bin" | |
<< std::endl << std::endl | |
<< " DIGEST: sha256|sha384|sha512|sha1|ripemd160" | |
<< std::endl; | |
return 1; | |
} | |
std::string digest {argv[1]}; | |
std::string filename_in {argv[2]}; | |
std::string filename_out {argv[3]}; | |
std::cout | |
<< "digest: " << digest << std::endl | |
<< "input filename: " << filename_in << std::endl | |
<< "output filename: " << filename_out << std::endl << std::endl; | |
try | |
{ | |
tr_gnutls::global_init g; | |
auto req {gen_req (digest, get_signature_value (filename_in))}; | |
if (req.size () == 0) | |
{ | |
std::cout << "generate failed" << std::endl; | |
return 1; | |
} | |
std::cout << "der_coding succeeded" << std::endl | |
<< tr_util::binary_hex (req) << std::flush; | |
std::cout << std::endl | |
<< "writing request file \"" << filename_out | |
<< "\"..." << std::endl; | |
tr_util::filesave (filename_out, req); | |
} | |
catch (std::runtime_error &e) | |
{ | |
std::cout << e.what () << std::endl; | |
return 1; | |
} | |
std::cout << std::endl << "complete" << std::endl; | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Global initializer for GnuTLS | |
// | |
// tr_gnutls_init.cc: | |
// Implementation | |
// | |
// Copyright (C) 2019 Masamichi Hosoda. | |
// All rights reserved. | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions | |
// are met: | |
// | |
// * Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// * Redistributions in binary form must reproduce the above copyright notice, | |
// this list of conditions and the following disclaimer in the documentation | |
// and/or other materials provided with the distribution. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
// ARE DISCLAIMED. | |
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
// SUCH DAMAGE. | |
// | |
#include "tr_gnutls_init.hh" | |
#include <stdexcept> | |
#include <sstream> | |
#include <string> | |
#include <gnutls/gnutls.h> | |
namespace tr_gnutls | |
{ | |
global_init::global_init () | |
{ | |
int ret = gnutls_global_init (); | |
if (ret < 0) | |
{ | |
std::stringstream ss; | |
ss << "tr_gnutls::global_init: gnutls_global_init failed " | |
<< ret; | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
} | |
global_init::~global_init () | |
{ | |
gnutls_global_deinit(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Global initializer for GnuTLS | |
// | |
// tr_gnutls_init.hh: | |
// Header file | |
// | |
// Copyright (C) 2019 Masamichi Hosoda. | |
// All rights reserved. | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions | |
// are met: | |
// | |
// * Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// * Redistributions in binary form must reproduce the above copyright notice, | |
// this list of conditions and the following disclaimer in the documentation | |
// and/or other materials provided with the distribution. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
// ARE DISCLAIMED. | |
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
// SUCH DAMAGE. | |
// | |
#ifndef INCLUDE_GUARD_TR_GNUTLS_INIT_HH | |
#define INCLUDE_GUARD_TR_GNUTLS_INIT_HH | |
namespace tr_gnutls | |
{ | |
class global_init | |
{ | |
public: | |
global_init (); | |
~global_init (); | |
global_init (const global_init &) = delete; | |
global_init& operator= (const global_init &) = delete; | |
global_init (global_init &&) = delete; | |
global_init& operator= (global_init &&) = delete; | |
}; | |
} | |
#endif // INCLUDE_GUARD_TR_GNUTLS_INIT_HH |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Random number generator using GnuTLS | |
// | |
// tr_gnutls_rnd.hh: | |
// Header file / implementation | |
// | |
// Copyright (C) 2019 Masamichi Hosoda. | |
// All rights reserved. | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions | |
// are met: | |
// | |
// * Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// * Redistributions in binary form must reproduce the above copyright notice, | |
// this list of conditions and the following disclaimer in the documentation | |
// and/or other materials provided with the distribution. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
// ARE DISCLAIMED. | |
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
// SUCH DAMAGE. | |
// | |
#ifndef INCLUDE_GUARD_TR_GNUTLS_RND_HH | |
#define INCLUDE_GUARD_TR_GNUTLS_RND_HH | |
#include <stdexcept> | |
#include <sstream> | |
#include <string> | |
#include <vector> | |
#include <gnutls/crypto.h> | |
namespace tr_gnutls | |
{ | |
inline | |
std::vector<unsigned char> rnd (gnutls_rnd_level_t level, size_t len) | |
{ | |
std::vector<unsigned char> buff (len); | |
int ret = gnutls_rnd (level, buff.data (), len); | |
if (ret < 0) | |
{ | |
std::stringstream ss; | |
ss << "tr_gnutls::rnd: gnutls_rnd failed: " | |
<< gnutls_strerror (ret); | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
return buff; | |
} | |
}; | |
#endif // INCLUDE_GUARD_TR_GNUTLS_RND_HH |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// tr_hash: C++ class library for hash calculation | |
// https://gist.github.com/trueroad/249bba7aaaada8eca8cab30dae8215b1 | |
// | |
// tr_hash.hh: | |
// Header file for tr_hash | |
// | |
// Copyright (C) 2019 Masamichi Hosoda. | |
// All rights reserved. | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions | |
// are met: | |
// | |
// * Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// * Redistributions in binary form must reproduce the above copyright notice, | |
// this list of conditions and the following disclaimer in the documentation | |
// and/or other materials provided with the distribution. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
// ARE DISCLAIMED. | |
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
// SUCH DAMAGE. | |
// | |
#ifndef INCLUDE_GUARD_TR_HASH_HH | |
#define INCLUDE_GUARD_TR_HASH_HH | |
#include <memory> | |
#include <string> | |
#include <vector> | |
namespace tr_hash | |
{ | |
class hash | |
{ | |
public: | |
hash (const std::string & /* name */); | |
~hash (); | |
hash (const hash &) = delete; | |
hash& operator= (const hash &) = delete; | |
hash (hash &&); | |
hash& operator= (hash &&); | |
explicit operator bool (); | |
std::vector<unsigned char> | |
calc (const std::vector<unsigned char> & /* input */); | |
std::string oid (); | |
private: | |
class impl; | |
std::unique_ptr<impl> pimpl_; | |
}; | |
} | |
#endif // INCLUDE_GUARD_TR_HASH_HH |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// tr_hash: C++ class library for hash calculation | |
// https://gist.github.com/trueroad/249bba7aaaada8eca8cab30dae8215b1 | |
// | |
// tr_hash_gnutls.cc: | |
// Implementation for tr_hash with GnuTLS | |
// | |
// Copyright (C) 2019 Masamichi Hosoda. | |
// All rights reserved. | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions | |
// are met: | |
// | |
// * Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// * Redistributions in binary form must reproduce the above copyright notice, | |
// this list of conditions and the following disclaimer in the documentation | |
// and/or other materials provided with the distribution. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
// ARE DISCLAIMED. | |
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
// SUCH DAMAGE. | |
// | |
#include "tr_hash.hh" | |
#include <memory> | |
#include <stdexcept> | |
#include <sstream> | |
#include <string> | |
#include <vector> | |
#include <gnutls/crypto.h> | |
namespace tr_hash | |
{ | |
class hash::impl | |
{ | |
public: | |
impl (const std::string &name); | |
~impl () = default; | |
impl (const impl &) = delete; | |
impl& operator= (const impl &) = delete; | |
impl (impl &&) = default; | |
impl& operator= (impl &&) = default; | |
explicit operator bool (); | |
std::vector<unsigned char> | |
calc (const std::vector<unsigned char> &input); | |
std::string oid (); | |
private: | |
gnutls_digest_algorithm_t algo_ = GNUTLS_DIG_UNKNOWN; | |
}; | |
hash::impl::impl (const std::string &name) | |
{ | |
if (name == "sha256") | |
algo_ = GNUTLS_DIG_SHA256; | |
else if (name == "sha384") | |
algo_ = GNUTLS_DIG_SHA384; | |
else if (name == "sha512") | |
algo_ = GNUTLS_DIG_SHA512; | |
else if (name == "sha1") | |
algo_ = GNUTLS_DIG_SHA1; | |
else if (name == "ripemd160") | |
algo_ = GNUTLS_DIG_RMD160; | |
} | |
hash::impl::operator bool () | |
{ | |
if (algo_ == GNUTLS_DIG_UNKNOWN) | |
return false; | |
return true; | |
} | |
std::vector<unsigned char> | |
hash::impl::calc (const std::vector<unsigned char> &input) | |
{ | |
auto len {gnutls_hash_get_len (algo_)}; | |
if (len == 0) | |
throw std::runtime_error("GnuTLS error: gnutls_hash_get_len: failed"); | |
std::vector<unsigned char> retval (len); | |
auto ret {gnutls_hash_fast (algo_, input.data (), input.size (), | |
retval.data ())}; | |
if (ret < 0) | |
{ | |
std::stringstream ss; | |
ss << "GnuTLS error: gnutls_hash_fast:" << gnutls_strerror (ret); | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
return retval; | |
} | |
std::string hash::impl::oid () | |
{ | |
switch (algo_) | |
{ | |
case GNUTLS_DIG_SHA256: | |
return "2.16.840.1.101.3.4.2.1"; | |
case GNUTLS_DIG_SHA384: | |
return "2.16.840.1.101.3.4.2.2"; | |
case GNUTLS_DIG_SHA512: | |
return "2.16.840.1.101.3.4.2.3"; | |
case GNUTLS_DIG_SHA1: | |
return "1.3.14.3.2.26"; | |
case GNUTLS_DIG_RMD160: | |
return "1.3.36.3.2.1"; | |
default: | |
break; | |
} | |
return ""; | |
} | |
hash::hash (const std::string &name): | |
pimpl_ (new hash::impl (name)) | |
{ | |
} | |
hash::~hash () = default; | |
hash::hash (hash &&) = default; | |
hash& hash::operator= (hash &&) = default; | |
hash::operator bool () | |
{ | |
return static_cast<bool> (*pimpl_); | |
} | |
std::vector<unsigned char> | |
hash::calc (const std::vector<unsigned char> &input) | |
{ | |
return pimpl_->calc (input); | |
} | |
std::string hash::oid () | |
{ | |
return pimpl_->oid (); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// tr_libtasn1: C++ class library for libtasn1 | |
// https://gist.github.com/trueroad/77165de4a367da4eaae7038658262063 | |
// | |
// tr_libtasn1.cc: | |
// Implementation for tr_libtasn1 | |
// | |
// Copyright (C) 2019, 2020 Masamichi Hosoda. | |
// All rights reserved. | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions | |
// are met: | |
// | |
// * Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// * Redistributions in binary form must reproduce the above copyright notice, | |
// this list of conditions and the following disclaimer in the documentation | |
// and/or other materials provided with the distribution. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
// ARE DISCLAIMED. | |
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
// SUCH DAMAGE. | |
// | |
#include "tr_libtasn1.hh" | |
#include <iostream> | |
#include <memory> | |
#include <sstream> | |
#include <string> | |
#include <stdexcept> | |
#include <libtasn1.h> | |
namespace tr_libtasn1 | |
{ | |
asn1_definition::asn1_definition (const asn1_static_node * array) | |
{ | |
asn1_node definitions = nullptr; | |
char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; | |
int asn1_result = asn1_array2tree (array, &definitions, errorDescription); | |
if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_array2tree error: " | |
<< asn1_strerror (asn1_result) | |
<< ", description: " << errorDescription; | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
definitions_.reset (definitions, | |
[] (asn1_node d) | |
{ | |
asn1_delete_structure (&d); | |
}); | |
} | |
asn1_definition::~asn1_definition () = default; | |
asn1_definition::asn1_definition (const asn1_definition &) = default; | |
asn1_definition& asn1_definition::operator= (const asn1_definition &) = | |
default; | |
asn1_definition::asn1_definition (asn1_definition &&) = default; | |
asn1_definition& asn1_definition::operator= (asn1_definition &&) = | |
default; | |
asn1_structure asn1_definition::create_element (const std::string &name) | |
{ | |
return asn1_structure (*this, name); | |
} | |
asn1_definition::operator asn1_node () const | |
{ | |
return definitions_.get (); | |
} | |
asn1_structure::asn1_structure (const asn1_definition &definition, | |
const std::string &name): | |
definition_ (definition) | |
{ | |
int asn1_result = asn1_create_element (definition_, | |
name.c_str (), | |
&structure_); | |
if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_create_element \"" | |
<< name << "\" error: " | |
<< asn1_strerror (asn1_result); | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
} | |
asn1_structure::~asn1_structure () | |
{ | |
asn1_delete_structure (&structure_); | |
} | |
asn1_structure::asn1_structure (asn1_structure &&) = default; | |
asn1_structure& asn1_structure::operator= (asn1_structure &&) = default; | |
void asn1_structure::delete_element (const std::string &name) | |
{ | |
int asn1_result = asn1_delete_element (structure_, | |
name.c_str ()); | |
if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_delete_element \"" | |
<< name << "\" error: " | |
<< asn1_strerror (asn1_result); | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
} | |
int asn1_structure::number_of_elements (const std::string &name) | |
{ | |
int num {0}; | |
int asn1_result = asn1_number_of_elements (structure_, | |
name.c_str (), | |
&num); | |
if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_number_of_elements \"" | |
<< name << "\" error: " | |
<< asn1_strerror (asn1_result); | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
return num; | |
} | |
int asn1_structure::number_of_elements_optional (const std::string &name) | |
{ | |
int num {0}; | |
int asn1_result = asn1_number_of_elements (structure_, | |
name.c_str (), | |
&num); | |
if (asn1_result == ASN1_ELEMENT_NOT_FOUND) | |
return 0; | |
else if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_number_of_elements \"" | |
<< name << "\" error: " | |
<< asn1_strerror (asn1_result); | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
return num; | |
} | |
void asn1_structure::copy_node (const std::string &dst_name, | |
const std::string &src_name) | |
{ | |
int asn1_result = asn1_copy_node (structure_, | |
dst_name.c_str (), | |
structure_, | |
src_name.c_str ()); | |
if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_copy_node dst \"" | |
<< dst_name << "\", src \"" << src_name << "\" error: " | |
<< asn1_strerror (asn1_result); | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
} | |
void asn1_structure::copy_node (const std::string &dst_name, | |
const asn1_structure &src_structure, | |
const std::string &src_name) | |
{ | |
int asn1_result = asn1_copy_node (structure_, | |
dst_name.c_str (), | |
src_structure, | |
src_name.c_str ()); | |
if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_copy_node dst \"" | |
<< dst_name << "\", src \"" << src_name << "\" error: " | |
<< asn1_strerror (asn1_result); | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
} | |
void asn1_structure::copy_node_optional (const std::string &dst_name, | |
const std::string &src_name) | |
{ | |
int asn1_result = asn1_copy_node (structure_, | |
dst_name.c_str (), | |
structure_, | |
src_name.c_str ()); | |
if (asn1_result == ASN1_ELEMENT_NOT_FOUND) | |
{ | |
asn1_result = asn1_delete_element (structure_, dst_name.c_str ()); | |
if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_delete_element dst \"" | |
<< dst_name << "\" error: " | |
<< asn1_strerror (asn1_result); | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
} | |
else if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_copy_node dst \"" | |
<< dst_name << "\", src \"" << src_name << "\" error: " | |
<< asn1_strerror (asn1_result); | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
} | |
void asn1_structure::write_value (const std::string &name, | |
const char *value, | |
int len) | |
{ | |
int asn1_result = asn1_write_value (structure_, | |
name.c_str (), | |
value, | |
len); | |
if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_write_value char* \"" | |
<< name << "\" error: " | |
<< asn1_strerror (asn1_result); | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
} | |
void asn1_structure::write_value (const std::string &name, | |
const std::vector<unsigned char> &value) | |
{ | |
int asn1_result = asn1_write_value (structure_, | |
name.c_str (), | |
value.data (), | |
value.size ()); | |
if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_write_value binary \"" | |
<< name << "\" error: " | |
<< asn1_strerror (asn1_result); | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
} | |
std::vector<unsigned char> | |
asn1_structure::read_value_binary (const std::string &name) | |
{ | |
std::vector<unsigned char> retval; | |
int len {0}; | |
int asn1_result = asn1_read_value (structure_, | |
name.c_str (), | |
nullptr, | |
&len); | |
if (asn1_result == ASN1_MEM_ERROR) | |
{ | |
retval.resize (len); | |
asn1_result = asn1_read_value (structure_, | |
name.c_str (), | |
retval.data (), | |
&len); | |
} | |
if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_read_value binary \"" | |
<< name << "\" error: " | |
<< asn1_strerror (asn1_result); | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
return retval; | |
} | |
std::string | |
asn1_structure::read_value_string (const std::string &name) | |
{ | |
std::string retval; | |
int len {0}; | |
int asn1_result = asn1_read_value (structure_, | |
name.c_str (), | |
nullptr, | |
&len); | |
if (asn1_result == ASN1_MEM_ERROR) | |
{ | |
retval.resize (len); | |
asn1_result = asn1_read_value (structure_, | |
name.c_str (), | |
&retval[0], | |
&len); | |
} | |
if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_read_value string \"" | |
<< name << "\" error: " | |
<< asn1_strerror (asn1_result); | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
if (retval.back () == 0) | |
retval.pop_back (); // remove zero termination | |
return retval; | |
} | |
int asn1_structure::read_value_int (const std::string &name) | |
{ | |
auto buff {read_value_binary (name)}; | |
if (buff.size () > sizeof (int)) | |
{ | |
throw std::runtime_error ("tr_libtasn1: " | |
"asn1_structure::read_value_int: " | |
"size overflow"); | |
} | |
int retval {*(reinterpret_cast<const char*> (&buff[0]))}; | |
for (int i = 1; i < buff.size (); ++i) | |
{ | |
retval = (retval << 8) | buff[i]; | |
} | |
return retval; | |
} | |
std::vector<unsigned char> | |
asn1_structure::der_coding (const std::string &name) | |
{ | |
std::vector<unsigned char> retval; | |
int der_len {0}; | |
char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; | |
int asn1_result = asn1_der_coding (structure_, | |
name.c_str (), | |
nullptr, | |
&der_len, | |
errorDescription); | |
if (asn1_result == ASN1_MEM_ERROR) | |
{ | |
retval.resize (der_len); | |
asn1_result = asn1_der_coding (structure_, | |
name.c_str (), | |
retval.data (), | |
&der_len, | |
errorDescription); | |
} | |
if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_der_coding \"" | |
<< name << "\" error: " | |
<< asn1_strerror (asn1_result) | |
<< ", description: " << errorDescription; | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
return retval; | |
} | |
void asn1_structure::der_decoding (const std::vector<unsigned char> &buffer) | |
{ | |
char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; | |
int asn1_result = asn1_der_decoding (&structure_, | |
buffer.data (), | |
buffer.size (), | |
errorDescription); | |
if (asn1_result != ASN1_SUCCESS) | |
{ | |
std::stringstream ss; | |
ss << "tr_libtasn1: asn1_der_decoding error: " | |
<< asn1_strerror (asn1_result) | |
<< ", description: " << errorDescription; | |
throw std::runtime_error (ss.str ().c_str ()); | |
} | |
} | |
asn1_structure::operator asn1_node () const | |
{ | |
return structure_; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// tr_libtasn1: C++ class library for libtasn1 | |
// https://gist.github.com/trueroad/77165de4a367da4eaae7038658262063 | |
// | |
// tr_libtasn1.hh: | |
// Header file for tr_libtasn1 | |
// | |
// Copyright (C) 2019, 2020 Masamichi Hosoda. | |
// All rights reserved. | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions | |
// are met: | |
// | |
// * Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// * Redistributions in binary form must reproduce the above copyright notice, | |
// this list of conditions and the following disclaimer in the documentation | |
// and/or other materials provided with the distribution. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
// ARE DISCLAIMED. | |
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
// SUCH DAMAGE. | |
// | |
#ifndef INCLUDE_GUARD_TR_LIBTASN1_HH | |
#define INCLUDE_GUARD_TR_LIBTASN1_HH | |
#include <memory> | |
#include <vector> | |
struct asn1_node_st; | |
typedef asn1_node_st *asn1_node; | |
struct asn1_static_node_st; | |
typedef struct asn1_static_node_st asn1_static_node; | |
namespace tr_libtasn1 | |
{ | |
class asn1_structure; | |
class asn1_definition | |
{ | |
public: | |
asn1_definition (const asn1_static_node * /* array */); | |
~asn1_definition (); | |
asn1_definition (const asn1_definition &); | |
asn1_definition& operator= (const asn1_definition &); | |
asn1_definition (asn1_definition &&); | |
asn1_definition& operator= (asn1_definition &&); | |
asn1_structure create_element (const std::string & /* name */); | |
operator asn1_node () const; | |
private: | |
std::shared_ptr<asn1_node_st> definitions_; | |
}; | |
class asn1_structure | |
{ | |
public: | |
asn1_structure (const asn1_definition & /* definition */, | |
const std::string & /* name */); | |
~asn1_structure (); | |
asn1_structure (const asn1_structure &) = delete; | |
asn1_structure& operator= (const asn1_structure &) = delete; | |
asn1_structure (asn1_structure &&); | |
asn1_structure& operator= (asn1_structure &&); | |
void delete_element (const std::string & /* name */); | |
int number_of_elements (const std::string & /* name */); | |
int number_of_elements_optional (const std::string & /* name */); | |
void copy_node (const std::string & /* dst_name */, | |
const std::string & /* src_name */); | |
void copy_node (const std::string & /* dst_name */, | |
const asn1_structure & /* src_structure */, | |
const std::string & /* src_name */); | |
void copy_node_optional (const std::string & /* dst_name */, | |
const std::string & /* src_name */); | |
void write_value (const std::string & /* name */, | |
const char * /* value */, | |
int len = 0); | |
void write_value (const std::string & /* name */, | |
const std::vector<unsigned char> & /* value */); | |
std::vector<unsigned char> | |
read_value_binary (const std::string & /* name */); | |
std::string | |
read_value_string (const std::string & /* name */); | |
int read_value_int (const std::string & /* name */); | |
std::vector<unsigned char> der_coding (const std::string & /* name */); | |
void der_decoding (const std::vector<unsigned char> & /* buffer */); | |
operator asn1_node () const; | |
private: | |
asn1_definition definition_; | |
asn1_node structure_ = nullptr; | |
}; | |
} | |
#endif // INCLUDE_GUARD_TR_LIBTASN1_HH |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Utility for binary files / data | |
// | |
// tr_util_binary.hh: | |
// Header file / implementation | |
// | |
// Copyright (C) 2019, 2020 Masamichi Hosoda. | |
// All rights reserved. | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions | |
// are met: | |
// | |
// * Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// * Redistributions in binary form must reproduce the above copyright notice, | |
// this list of conditions and the following disclaimer in the documentation | |
// and/or other materials provided with the distribution. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
// ARE DISCLAIMED. | |
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
// SUCH DAMAGE. | |
// | |
#ifndef INCLUDE_GUARD_TR_UTIL_BINARY_HH | |
#define INCLUDE_GUARD_TR_UTIL_BINARY_HH | |
#include <fstream> | |
#include <iomanip> | |
#include <stdexcept> | |
#include <sstream> | |
#include <string> | |
#include <vector> | |
namespace tr_util | |
{ | |
inline | |
std::string binary_hex (const std::vector<unsigned char> &buff) | |
{ | |
std::stringstream ss; | |
ss << std::hex; | |
for (int i = 0; i < buff.size (); ++i) | |
{ | |
if ((i % 16) == 0 && i) | |
ss << std::endl; | |
ss << std::setw (2) << std::setfill ('0') | |
<< static_cast<unsigned int> (buff[i]) << " "; | |
} | |
ss << std::endl; | |
return ss.str (); | |
} | |
inline | |
std::vector<unsigned char> fileload_binary (const std::string &filename) | |
{ | |
std::ifstream ifs (filename, std::ios::binary); | |
if (!ifs) | |
throw std::runtime_error ("tr_util::fileload_binary: " | |
"std::ifstream failed"); | |
ifs.seekg (0, std::ios::end); | |
auto eof {ifs.tellg ()}; | |
ifs.clear (); | |
ifs.seekg (0, std::ios::beg); | |
std::vector<unsigned char> buff (eof); | |
ifs.read (reinterpret_cast<char*> (buff.data ()), buff.size ()); | |
return buff; | |
} | |
inline void filesave (const std::string &filename, | |
const std::vector<unsigned char> &buff) | |
{ | |
std::ofstream ofs (filename, std::ios::binary); | |
if (!ofs) | |
throw std::runtime_error ("tr_util::filesave: " | |
"std::ofstream failed"); | |
ofs.write (reinterpret_cast<const char*> (buff.data ()), buff.size ()); | |
} | |
} | |
#endif // INCLUDE_GUARD_TR_UTIL_BINARY_HH |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- From RFC 3161 -- | |
PKIXTSP {iso(1) identified-organization(3) dod(6) internet(1) | |
security(5) mechanisms(5) pkix(7) id-mod(0) id-mod-tsp(13)} | |
DEFINITIONS IMPLICIT TAGS ::= | |
BEGIN | |
-- 2.4.1 | |
TimeStampReq ::= SEQUENCE { | |
version INTEGER { v1(1) }, | |
messageImprint MessageImprint, | |
--a hash algorithm OID and the hash value of the data to be | |
--time-stamped | |
reqPolicy TSAPolicyId OPTIONAL, | |
nonce INTEGER OPTIONAL, | |
certReq BOOLEAN DEFAULT FALSE, | |
extensions [0] IMPLICIT Extensions OPTIONAL } | |
MessageImprint ::= SEQUENCE { | |
hashAlgorithm AlgorithmIdentifier, | |
hashedMessage OCTET STRING } | |
TSAPolicyId ::= OBJECT IDENTIFIER | |
-- 2.4.2 | |
TimeStampResp ::= SEQUENCE { | |
status PKIStatusInfo, | |
timeStampToken TimeStampToken OPTIONAL } | |
-- The status is based on the definition of status | |
-- in section 3.2.3 of [RFC2510] | |
PKIStatusInfo ::= SEQUENCE { | |
status PKIStatus, | |
statusString PKIFreeText OPTIONAL, | |
failInfo PKIFailureInfo OPTIONAL } | |
PKIStatus ::= INTEGER { | |
granted (0), | |
-- when the PKIStatus contains the value zero a TimeStampToken, as | |
-- requested, is present. | |
grantedWithMods (1), | |
-- when the PKIStatus contains the value one a TimeStampToken, | |
-- with modifications, is present. | |
rejection (2), | |
waiting (3), | |
revocationWarning (4), | |
-- this message contains a warning that a revocation is | |
-- imminent | |
revocationNotification (5) | |
-- notification that a revocation has occurred | |
} | |
-- When the TimeStampToken is not present | |
-- failInfo indicates the reason why the | |
-- time-stamp request was rejected and | |
-- may be one of the following values. | |
PKIFailureInfo ::= BIT STRING { | |
badAlg (0), | |
-- unrecognized or unsupported Algorithm Identifier | |
badRequest (2), | |
-- transaction not permitted or supported | |
badDataFormat (5), | |
-- the data submitted has the wrong format | |
timeNotAvailable (14), | |
-- the TSA's time source is not available | |
unacceptedPolicy (15), | |
-- the requested TSA policy is not supported by the TSA. | |
unacceptedExtension (16), | |
-- the requested extension is not supported by the TSA. | |
addInfoNotAvailable (17), | |
-- the additional information requested could not be understood | |
-- or is not available | |
systemFailure (25) | |
-- the request cannot be handled due to system failure | |
} | |
TimeStampToken ::= ContentInfo | |
-- contentType is id-signedData as defined in [CMS] | |
-- content is SignedData as defined in([CMS]) | |
-- eContentType within SignedData is id-ct-TSTInfo | |
-- eContent within SignedData is TSTInfo | |
TSTInfo ::= SEQUENCE { | |
version INTEGER { v1(1) }, | |
policy TSAPolicyId, | |
messageImprint MessageImprint, | |
-- MUST have the same value as the similar field in | |
-- TimeStampReq | |
serialNumber INTEGER, | |
-- Time-Stamping users MUST be ready to accommodate integers | |
-- up to 160 bits. | |
genTime GeneralizedTime, | |
accuracy Accuracy OPTIONAL, | |
ordering BOOLEAN DEFAULT FALSE, | |
nonce INTEGER OPTIONAL, | |
-- MUST be present if the similar field was present | |
-- in TimeStampReq. In that case it MUST have the same value. | |
tsa [0] GeneralName OPTIONAL, | |
extensions [1] IMPLICIT Extensions OPTIONAL } | |
Accuracy ::= SEQUENCE { | |
seconds INTEGER OPTIONAL, | |
millis [0] INTEGER (1..999) OPTIONAL, | |
micros [1] INTEGER (1..999) OPTIONAL } | |
-- ... -- | |
-- From RFC 2459 / 3280 / 5280 -- | |
-- ... -- | |
Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension | |
Extension ::= SEQUENCE { | |
extnID OBJECT IDENTIFIER, | |
critical BOOLEAN DEFAULT FALSE, | |
extnValue OCTET STRING | |
-- contains the DER encoding of an ASN.1 value | |
-- corresponding to the extension type identified | |
-- by extnID | |
} | |
-- ... -- | |
AlgorithmIdentifier ::= SEQUENCE { | |
algorithm OBJECT IDENTIFIER, | |
parameters ANY DEFINED BY algorithm OPTIONAL } | |
-- contains a value of the type | |
-- registered for use with the | |
-- algorithm object identifier value | |
-- ... -- | |
-- From RFC 2510 / 4210 -- | |
-- ... -- | |
PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String | |
-- text encoded as UTF-8 String [RFC3629] (note: each | |
-- UTF8String MAY include an [RFC3066] language tag | |
-- to indicate the language of the contained text | |
-- see [RFC2482] for details) | |
-- ... -- | |
-- From RFC 2630 / 3369 / 3852 / 5652 -- | |
-- ... -- | |
-- Cryptographic Message Syntax | |
ContentInfo ::= SEQUENCE { | |
contentType ContentType, | |
content [0] EXPLICIT ANY DEFINED BY contentType } | |
ContentType ::= OBJECT IDENTIFIER | |
-- ... -- | |
-- From RFC 5280 -- | |
-- ... -- | |
GeneralName ::= CHOICE { | |
otherName [0] AnotherName, | |
rfc822Name [1] IA5String, | |
dNSName [2] IA5String, | |
x400Address [3] ORAddress, | |
directoryName [4] Name, | |
ediPartyName [5] EDIPartyName, | |
uniformResourceIdentifier [6] IA5String, | |
iPAddress [7] OCTET STRING, | |
registeredID [8] OBJECT IDENTIFIER } | |
-- ... -- | |
-- dummy -- | |
-- RFC 5280 | |
AnotherName ::= SEQUENCE OF ANY | |
ORAddress ::= SEQUENCE OF ANY | |
Name ::= SEQUENCE OF ANY | |
EDIPartyName ::= SEQUENCE OF ANY | |
END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if HAVE_CONFIG_H | |
# include "config.h" | |
#endif | |
#include <libtasn1.h> | |
const asn1_static_node ts_asn1_tab[] = { | |
{ "PKIXTSP", 536875024, NULL }, | |
{ NULL, 1610612748, NULL }, | |
{ "iso", 1073741825, "1"}, | |
{ "identified-organization", 1073741825, "3"}, | |
{ "dod", 1073741825, "6"}, | |
{ "internet", 1073741825, "1"}, | |
{ "security", 1073741825, "5"}, | |
{ "mechanisms", 1073741825, "5"}, | |
{ "pkix", 1073741825, "7"}, | |
{ "id-mod", 1073741825, "0"}, | |
{ "id-mod-tsp", 1, "13"}, | |
{ "TimeStampReq", 1610612741, NULL }, | |
{ "version", 1610874883, NULL }, | |
{ "v1", 1, "1"}, | |
{ "messageImprint", 1073741826, "MessageImprint"}, | |
{ "reqPolicy", 1073758210, "TSAPolicyId"}, | |
{ "nonce", 1073758211, NULL }, | |
{ "certReq", 1610645508, NULL }, | |
{ NULL, 131081, NULL }, | |
{ "extensions", 536895490, "Extensions"}, | |
{ NULL, 4104, "0"}, | |
{ "MessageImprint", 1610612741, NULL }, | |
{ "hashAlgorithm", 1073741826, "AlgorithmIdentifier"}, | |
{ "hashedMessage", 7, NULL }, | |
{ "TSAPolicyId", 1073741836, NULL }, | |
{ "TimeStampResp", 1610612741, NULL }, | |
{ "status", 1073741826, "PKIStatusInfo"}, | |
{ "timeStampToken", 16386, "TimeStampToken"}, | |
{ "PKIStatusInfo", 1610612741, NULL }, | |
{ "status", 1073741826, "PKIStatus"}, | |
{ "statusString", 1073758210, "PKIFreeText"}, | |
{ "failInfo", 16386, "PKIFailureInfo"}, | |
{ "PKIStatus", 1610874883, NULL }, | |
{ "granted", 1073741825, "0"}, | |
{ "grantedWithMods", 1073741825, "1"}, | |
{ "rejection", 1073741825, "2"}, | |
{ "waiting", 1073741825, "3"}, | |
{ "revocationWarning", 1073741825, "4"}, | |
{ "revocationNotification", 1, "5"}, | |
{ "PKIFailureInfo", 1610874886, NULL }, | |
{ "badAlg", 1073741825, "0"}, | |
{ "badRequest", 1073741825, "2"}, | |
{ "badDataFormat", 1073741825, "5"}, | |
{ "timeNotAvailable", 1073741825, "14"}, | |
{ "unacceptedPolicy", 1073741825, "15"}, | |
{ "unacceptedExtension", 1073741825, "16"}, | |
{ "addInfoNotAvailable", 1073741825, "17"}, | |
{ "systemFailure", 1, "25"}, | |
{ "TimeStampToken", 1073741826, "ContentInfo"}, | |
{ "TSTInfo", 1610612741, NULL }, | |
{ "version", 1610874883, NULL }, | |
{ "v1", 1, "1"}, | |
{ "policy", 1073741826, "TSAPolicyId"}, | |
{ "messageImprint", 1073741826, "MessageImprint"}, | |
{ "serialNumber", 1073741827, NULL }, | |
{ "genTime", 1073741861, NULL }, | |
{ "accuracy", 1073758210, "Accuracy"}, | |
{ "ordering", 1610645508, NULL }, | |
{ NULL, 131081, NULL }, | |
{ "nonce", 1073758211, NULL }, | |
{ "tsa", 1610637314, "GeneralName"}, | |
{ NULL, 4104, "0"}, | |
{ "extensions", 536895490, "Extensions"}, | |
{ NULL, 4104, "1"}, | |
{ "Accuracy", 1610612741, NULL }, | |
{ "seconds", 1073758211, NULL }, | |
{ "millis", 1611161603, NULL }, | |
{ NULL, 1073745928, "0"}, | |
{ "1", 10, "999"}, | |
{ "micros", 537419779, NULL }, | |
{ NULL, 1073745928, "1"}, | |
{ "1", 10, "999"}, | |
{ "Extensions", 1612709899, NULL }, | |
{ "MAX", 1074266122, "1"}, | |
{ NULL, 2, "Extension"}, | |
{ "Extension", 1610612741, NULL }, | |
{ "extnID", 1073741836, NULL }, | |
{ "critical", 1610645508, NULL }, | |
{ NULL, 131081, NULL }, | |
{ "extnValue", 7, NULL }, | |
{ "AlgorithmIdentifier", 1610612741, NULL }, | |
{ "algorithm", 1073741836, NULL }, | |
{ "parameters", 541081613, NULL }, | |
{ "algorithm", 1, NULL }, | |
{ "PKIFreeText", 1612709899, NULL }, | |
{ "MAX", 1074266122, "1"}, | |
{ NULL, 34, NULL }, | |
{ "ContentInfo", 1610612741, NULL }, | |
{ "contentType", 1073741826, "ContentType"}, | |
{ "content", 541073421, NULL }, | |
{ NULL, 1073743880, "0"}, | |
{ "contentType", 1, NULL }, | |
{ "ContentType", 1073741836, NULL }, | |
{ "GeneralName", 1610612754, NULL }, | |
{ "otherName", 1610620930, "AnotherName"}, | |
{ NULL, 4104, "0"}, | |
{ "rfc822Name", 1610620957, NULL }, | |
{ NULL, 4104, "1"}, | |
{ "dNSName", 1610620957, NULL }, | |
{ NULL, 4104, "2"}, | |
{ "x400Address", 1610620930, "ORAddress"}, | |
{ NULL, 4104, "3"}, | |
{ "directoryName", 1610620930, "Name"}, | |
{ NULL, 4104, "4"}, | |
{ "ediPartyName", 1610620930, "EDIPartyName"}, | |
{ NULL, 4104, "5"}, | |
{ "uniformResourceIdentifier", 1610620957, NULL }, | |
{ NULL, 4104, "6"}, | |
{ "iPAddress", 1610620935, NULL }, | |
{ NULL, 4104, "7"}, | |
{ "registeredID", 536879116, NULL }, | |
{ NULL, 4104, "8"}, | |
{ "AnotherName", 1610612747, NULL }, | |
{ NULL, 13, NULL }, | |
{ "ORAddress", 1610612747, NULL }, | |
{ NULL, 13, NULL }, | |
{ "Name", 1610612747, NULL }, | |
{ NULL, 13, NULL }, | |
{ "EDIPartyName", 536870923, NULL }, | |
{ NULL, 13, NULL }, | |
{ NULL, 0, NULL } | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Time stamp (RFC 3161) tools | |
// https://gist.github.com/trueroad/40072532a258b3519c8f6beabe829b0c | |
// | |
// ts_req.cc: | |
// Time stamp request generator | |
// | |
// Copyright (C) 2019 Masamichi Hosoda. | |
// All rights reserved. | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions | |
// are met: | |
// | |
// * Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// * Redistributions in binary form must reproduce the above copyright notice, | |
// this list of conditions and the following disclaimer in the documentation | |
// and/or other materials provided with the distribution. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
// ARE DISCLAIMED. | |
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
// SUCH DAMAGE. | |
// | |
#include <fstream> | |
#include <iostream> | |
#include <stdexcept> | |
#include <string> | |
#include <vector> | |
#include "tr_gnutls_init.hh" | |
#include "tr_util_binary.hh" | |
#include "ts_req_gen_req.hh" | |
extern "C" const asn1_static_node ts_asn1_tab[]; | |
int main (int argc, char *argv[]) | |
{ | |
std::cout | |
<< "Time stamp request (RFC 3161) generator" | |
<< std::endl | |
<< "Copyright (C) 2019 Masamichi Hosoda" | |
<< std::endl << std::endl; | |
if (argc != 4) | |
{ | |
std::cout | |
<< "usage: " << argv[0] | |
<< " DIGEST (in)TO-BE-SIGNED.bin (out)TIME-STAMP-REQUEST.bin" | |
<< std::endl << std::endl | |
<< " DIGEST: sha256|sha384|sha512|sha1|ripemd160" | |
<< std::endl; | |
return 1; | |
} | |
std::string digest {argv[1]}; | |
std::string filename_in {argv[2]}; | |
std::string filename_out {argv[3]}; | |
std::cout | |
<< "digest: " << digest << std::endl | |
<< "input filename: " << filename_in << std::endl | |
<< "output filename: " << filename_out << std::endl << std::endl; | |
try | |
{ | |
tr_gnutls::global_init g; | |
auto req {gen_req (digest, tr_util::fileload_binary (filename_in))}; | |
if (req.size () == 0) | |
{ | |
std::cout << "generate failed" << std::endl; | |
return 1; | |
} | |
std::cout << "der_coding succeeded" << std::endl | |
<< tr_util::binary_hex (req) << std::flush; | |
std::cout << std::endl | |
<< "writing request file \"" << filename_out | |
<< "\"..." << std::endl; | |
tr_util::filesave (filename_out, req); | |
} | |
catch (std::runtime_error &e) | |
{ | |
std::cout << e.what () << std::endl; | |
return 1; | |
} | |
std::cout << std::endl << "complete" << std::endl; | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Time stamp (RFC 3161) tools | |
// https://gist.github.com/trueroad/40072532a258b3519c8f6beabe829b0c | |
// | |
// ts_req_gen_req.hh: | |
// Time stamp request generation implementation | |
// | |
// Copyright (C) 2019 Masamichi Hosoda. | |
// All rights reserved. | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions | |
// are met: | |
// | |
// * Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// * Redistributions in binary form must reproduce the above copyright notice, | |
// this list of conditions and the following disclaimer in the documentation | |
// and/or other materials provided with the distribution. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
// ARE DISCLAIMED. | |
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
// SUCH DAMAGE. | |
// | |
#ifndef INCLUDE_GUARD_TS_REQ_GEN_REQ_HH | |
#define INCLUDE_GUARD_TS_REQ_GEN_REQ_HH | |
#include <gnutls/crypto.h> | |
#include "tr_gnutls_rnd.hh" | |
#include "tr_hash.hh" | |
#include "tr_libtasn1.hh" | |
extern "C" const asn1_static_node ts_asn1_tab[]; | |
inline | |
std::vector<unsigned char> | |
gen_nonce () | |
{ | |
auto nonce {tr_gnutls::rnd (GNUTLS_RND_NONCE, 8)}; | |
while (nonce[0] == 0 && | |
nonce.size () > 1 && (nonce[1] & 0x80) == 0) | |
nonce.erase (nonce.begin ()); | |
while (nonce[0] == 0xff && | |
nonce.size () > 1 && (nonce[1] & 0x80) != 0) | |
nonce.erase (nonce.begin ()); | |
return nonce; | |
} | |
inline | |
std::vector<unsigned char> | |
gen_req (const std::string &digest, const std::vector<unsigned char> &data) | |
{ | |
tr_hash::hash h (digest); | |
if (!h) | |
{ | |
throw std::runtime_error ("unknown digest"); | |
} | |
tr_libtasn1::asn1_definition d (ts_asn1_tab); | |
auto s {d.create_element ("PKIXTSP.TimeStampReq")}; | |
s.write_value ("messageImprint.hashAlgorithm.algorithm", | |
h.oid ().c_str ()); | |
auto md {h.calc (data)}; | |
s.write_value ("messageImprint.hashedMessage", md); | |
s.write_value ("nonce", gen_nonce ()); | |
s.write_value ("version", "1"); | |
s.write_value ("certReq", "TRUE"); | |
s.write_value ("messageImprint.hashAlgorithm.parameters", nullptr); | |
s.write_value ("reqPolicy", nullptr); | |
s.write_value ("extensions", nullptr); | |
return s.der_coding (""); | |
} | |
#endif // INCLUDE_GUARD_TS_REQ_GEN_REQ_HH |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Time stamp (RFC 3161) tools | |
// https://gist.github.com/trueroad/40072532a258b3519c8f6beabe829b0c | |
// | |
// ts_resp.cc: | |
// Time stamp response parser | |
// | |
// Copyright (C) 2019 Masamichi Hosoda. | |
// All rights reserved. | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions | |
// are met: | |
// | |
// * Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// * Redistributions in binary form must reproduce the above copyright notice, | |
// this list of conditions and the following disclaimer in the documentation | |
// and/or other materials provided with the distribution. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
// ARE DISCLAIMED. | |
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
// SUCH DAMAGE. | |
// | |
#include <fstream> | |
#include <iostream> | |
#include <stdexcept> | |
#include <string> | |
#include <vector> | |
#include "tr_libtasn1.hh" | |
#include "tr_util_binary.hh" | |
extern "C" const asn1_static_node ts_asn1_tab[]; | |
extern "C" const asn1_static_node cms_asn1_tab[]; | |
int main (int argc, char *argv[]) | |
{ | |
std::cout | |
<< "Time stamp response (RFC 3161) parser" | |
<< std::endl | |
<< "Copyright (C) 2019 Masamichi Hosoda" | |
<< std::endl << std::endl; | |
if (argc != 4) | |
{ | |
std::cout | |
<< "usage: " << argv[0] | |
<< " (in)TIME-STAMP-REQUEST.bin (in)TIME-STAMP-RESPONSE.bin" | |
" (out)TIME-STAMP-TOKEN.p7s" | |
<< std::endl; | |
return 1; | |
} | |
std::string filename_req {argv[1]}; | |
std::string filename_resp {argv[2]}; | |
std::string filename_token {argv[3]}; | |
std::cout | |
<< "request filename: " << filename_req << std::endl | |
<< "response filename: " << filename_resp << std::endl | |
<< "token filename: " << filename_token << std::endl << std::endl; | |
try | |
{ | |
tr_libtasn1::asn1_definition d_ts (ts_asn1_tab); | |
auto s_req {d_ts.create_element ("PKIXTSP.TimeStampReq")}; | |
s_req.der_decoding (tr_util::fileload_binary (filename_req)); | |
std::cout << "TimeStampReq:" << std::endl | |
<< " messageImprint:" << std::endl | |
<< " hashAlgorithm:" << std::endl | |
<< " algorithm: "; | |
auto algo_req {s_req.read_value_string | |
("messageImprint.hashAlgorithm.algorithm")}; | |
std::cout << algo_req << std::endl; | |
std::cout << " hashedMessage:" << std::endl; | |
auto hash_req {s_req.read_value_binary | |
("messageImprint.hashedMessage")}; | |
std::cout << tr_util::binary_hex (hash_req) << std::flush; | |
std::cout << " nonce:" << std::endl; | |
auto nonce_req {s_req.read_value_binary ("nonce")}; | |
std::cout << tr_util::binary_hex (nonce_req) << std::flush; | |
std::cout << std::endl; | |
auto s_resp {d_ts.create_element ("PKIXTSP.TimeStampResp")}; | |
s_resp.der_decoding (tr_util::fileload_binary (filename_resp)); | |
std::cout << "TimeStampResp:" << std::endl | |
<< " status:" << std::endl | |
<< " status: "; | |
auto resp_status {s_resp.read_value_int ("status.status")}; | |
std::cout << resp_status << std::endl; | |
if (! (resp_status == 0 || resp_status == 1)) | |
{ | |
std::cout << "failed" << std::endl; | |
return 1; | |
} | |
std::cout << " timeStampToken:" << std::endl | |
<< " contentType: "; | |
auto content_type | |
{s_resp.read_value_string ("timeStampToken.contentType")}; | |
std::cout << content_type << std::endl; | |
if (content_type != "1.2.840.113549.1.7.2") | |
{ | |
std::cout << "contentType different" << std::endl; | |
return 1; | |
} | |
auto signed_data {s_resp.read_value_binary ("timeStampToken.content")}; | |
tr_libtasn1::asn1_definition d_cms (cms_asn1_tab); | |
auto s_sign {d_cms.create_element | |
("CryptographicMessageSyntax2004.SignedData")}; | |
s_sign.der_decoding (signed_data); | |
std::cout << " content: (SignedData)" << std::endl | |
<< " encapContentInfo:" << std::endl | |
<< " eContentType: "; | |
auto econtent_type | |
{s_sign.read_value_string ("encapContentInfo.eContentType")}; | |
std::cout << econtent_type << std::endl; | |
if (econtent_type != "1.2.840.113549.1.9.16.1.4") | |
{ | |
std::cout << "eContentType different" << std::endl; | |
return 1; | |
} | |
auto tst_info {s_sign.read_value_binary ("encapContentInfo.eContent")}; | |
auto s_tst {d_ts.create_element ("PKIXTSP.TSTInfo")}; | |
s_tst.der_decoding (tst_info); | |
std::cout << " eContent: (TSTInfo)" << std::endl | |
<< " messageImprint:" << std::endl | |
<< " hashAlgorithm:" << std::endl | |
<< " algorithm: "; | |
auto algo_resp {s_req.read_value_string | |
("messageImprint.hashAlgorithm.algorithm")}; | |
std::cout << algo_resp << std::endl; | |
if (algo_req != algo_resp) | |
{ | |
std::cout << "algorithm different" << std::endl; | |
return 1; | |
} | |
std::cout << " hashedMessage:" << std::endl; | |
auto hash_resp {s_req.read_value_binary | |
("messageImprint.hashedMessage")}; | |
std::cout << tr_util::binary_hex (hash_resp) << std::flush; | |
if (hash_req != hash_resp) | |
{ | |
std::cout << "hash different" << std::endl; | |
return 1; | |
} | |
std::cout << " nonce:" << std::endl; | |
auto nonce_resp {s_tst.read_value_binary ("nonce")}; | |
std::cout << tr_util::binary_hex (nonce_resp) << std::flush; | |
if (nonce_req != nonce_resp) | |
{ | |
std::cout << "nonce different" << std::endl; | |
return 1; | |
} | |
auto token {s_resp.der_coding ("timeStampToken")}; | |
std::cout << std::endl | |
<< "writing token file \"" << filename_token | |
<< "\"..." << std::endl; | |
tr_util::filesave (filename_token, token); | |
} | |
catch (std::runtime_error &e) | |
{ | |
std::cout << e.what () << std::endl; | |
return 1; | |
} | |
std::cout << std::endl << "complete" << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment