1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
/*************************************************
* X.509 SIGNED Object Source File *
* (C) 1999-2005 The Botan Project *
*************************************************/
#include <botan/x509_obj.h>
#include <botan/parsing.h>
#include <botan/pem.h>
namespace Botan {
/*************************************************
* Create a generic X.509 object *
*************************************************/
X509_Object::X509_Object(DataSource& stream, const std::string& labels)
{
init(stream, labels);
}
/*************************************************
* Createa a generic X.509 object *
*************************************************/
X509_Object::X509_Object(const std::string& file, const std::string& labels)
{
DataSource_Stream stream(file, true);
init(stream, labels);
}
/*************************************************
* Read a PEM or BER X.509 object *
*************************************************/
void X509_Object::init(DataSource& in, const std::string& labels)
{
PEM_labels_allowed = split_on(labels, '/');
if(PEM_labels_allowed.size() < 1)
throw Invalid_Argument("Bad labels argument to X509_Object");
PEM_label_pref = PEM_labels_allowed[0];
std::sort(PEM_labels_allowed.begin(), PEM_labels_allowed.end());
try {
if(BER::maybe_BER(in) && !PEM_Code::matches(in))
decode_info(in);
else
{
std::string got_label;
DataSource_Memory ber(PEM_Code::decode(in, got_label));
if(!std::binary_search(PEM_labels_allowed.begin(),
PEM_labels_allowed.end(), got_label))
throw Decoding_Error("Invalid PEM label: " + got_label);
decode_info(ber);
}
}
catch(Decoding_Error)
{
throw Decoding_Error(PEM_label_pref + " decoding failed");
}
}
/*************************************************
* Read a BER encoded X.509 object *
*************************************************/
void X509_Object::decode_info(DataSource& source)
{
BER_Decoder ber(source);
BER_Decoder sequence = BER::get_subsequence(ber);
tbs_bits = BER::get_subsequence(sequence).get_remaining();
BER::decode(sequence, sig_algo);
BER::decode(sequence, sig, BIT_STRING);
sequence.verify_end();
}
/*************************************************
* Return a BER or PEM encoded X.509 object *
*************************************************/
void X509_Object::encode(Pipe& out, X509_Encoding encoding) const
{
DER_Encoder encoder;
encoder.start_sequence();
encoder.add_raw_octets(tbs_data());
DER::encode(encoder, sig_algo);
DER::encode(encoder, sig, BIT_STRING);
encoder.end_sequence();
SecureVector<byte> der = encoder.get_contents();
if(encoding == PEM)
out.write(PEM_Code::encode(der, PEM_label_pref));
else
out.write(der);
}
/*************************************************
* Return a BER encoded X.509 object *
*************************************************/
SecureVector<byte> X509_Object::BER_encode() const
{
Pipe ber;
ber.start_msg();
encode(ber, RAW_BER);
ber.end_msg();
return ber.read_all();
}
/*************************************************
* Return a PEM encoded X.509 object *
*************************************************/
std::string X509_Object::PEM_encode() const
{
Pipe pem;
pem.start_msg();
encode(pem, PEM);
pem.end_msg();
return pem.read_all_as_string();
}
/*************************************************
* Return the TBS data *
*************************************************/
SecureVector<byte> X509_Object::tbs_data() const
{
return DER::put_in_sequence(tbs_bits);
}
/*************************************************
* Return the signature of this object *
*************************************************/
SecureVector<byte> X509_Object::signature() const
{
return sig;
}
/*************************************************
* Return the algorithm used to sign this object *
*************************************************/
AlgorithmIdentifier X509_Object::signature_algorithm() const
{
return sig_algo;
}
/*************************************************
* Try to decode the actual information *
*************************************************/
void X509_Object::do_decode()
{
try {
force_decode();
}
catch(Decoding_Error& e)
{
const std::string what = e.what();
throw Decoding_Error(PEM_label_pref + " decoding failed (" +
what.substr(23, std::string::npos) + ")");
}
catch(Invalid_Argument& e)
{
const std::string what = e.what();
throw Decoding_Error(PEM_label_pref + " decoding failed (" +
what.substr(7, std::string::npos) + ")");
}
}
}
|