Botan  1.11.15
src/lib/asn1/der_enc.cpp
Go to the documentation of this file.
00001 /*
00002 * DER Encoder
00003 * (C) 1999-2007 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/der_enc.h>
00009 #include <botan/asn1_obj.h>
00010 #include <botan/bigint.h>
00011 #include <botan/get_byte.h>
00012 #include <botan/parsing.h>
00013 #include <botan/internal/bit_ops.h>
00014 #include <algorithm>
00015 
00016 namespace Botan {
00017 
00018 namespace {
00019 
00020 /*
00021 * DER encode an ASN.1 type tag
00022 */
00023 secure_vector<byte> encode_tag(ASN1_Tag type_tag, ASN1_Tag class_tag)
00024    {
00025    if((class_tag | 0xE0) != 0xE0)
00026       throw Encoding_Error("DER_Encoder: Invalid class tag " +
00027                            std::to_string(class_tag));
00028 
00029    secure_vector<byte> encoded_tag;
00030    if(type_tag <= 30)
00031       encoded_tag.push_back(static_cast<byte>(type_tag | class_tag));
00032    else
00033       {
00034       size_t blocks = high_bit(type_tag) + 6;
00035       blocks = (blocks - (blocks % 7)) / 7;
00036 
00037       encoded_tag.push_back(class_tag | 0x1F);
00038       for(size_t i = 0; i != blocks - 1; ++i)
00039          encoded_tag.push_back(0x80 | ((type_tag >> 7*(blocks-i-1)) & 0x7F));
00040       encoded_tag.push_back(type_tag & 0x7F);
00041       }
00042 
00043    return encoded_tag;
00044    }
00045 
00046 /*
00047 * DER encode an ASN.1 length field
00048 */
00049 secure_vector<byte> encode_length(size_t length)
00050    {
00051    secure_vector<byte> encoded_length;
00052    if(length <= 127)
00053       encoded_length.push_back(static_cast<byte>(length));
00054    else
00055       {
00056       const size_t top_byte = significant_bytes(length);
00057 
00058       encoded_length.push_back(static_cast<byte>(0x80 | top_byte));
00059 
00060       for(size_t i = sizeof(length) - top_byte; i != sizeof(length); ++i)
00061          encoded_length.push_back(get_byte(i, length));
00062       }
00063    return encoded_length;
00064    }
00065 
00066 }
00067 
00068 /*
00069 * Return the encoded SEQUENCE/SET
00070 */
00071 secure_vector<byte> DER_Encoder::DER_Sequence::get_contents()
00072    {
00073    const ASN1_Tag real_class_tag = ASN1_Tag(class_tag | CONSTRUCTED);
00074 
00075    if(type_tag == SET)
00076       {
00077       std::sort(set_contents.begin(), set_contents.end());
00078       for(size_t i = 0; i != set_contents.size(); ++i)
00079          contents += set_contents[i];
00080       set_contents.clear();
00081       }
00082 
00083    secure_vector<byte> result;
00084    result += encode_tag(type_tag, real_class_tag);
00085    result += encode_length(contents.size());
00086    result += contents;
00087    contents.clear();
00088 
00089    return result;
00090    }
00091 
00092 /*
00093 * Add an encoded value to the SEQUENCE/SET
00094 */
00095 void DER_Encoder::DER_Sequence::add_bytes(const byte data[], size_t length)
00096    {
00097    if(type_tag == SET)
00098       set_contents.push_back(secure_vector<byte>(data, data + length));
00099    else
00100       contents += std::make_pair(data, length);
00101    }
00102 
00103 /*
00104 * Return the type and class taggings
00105 */
00106 ASN1_Tag DER_Encoder::DER_Sequence::tag_of() const
00107    {
00108    return ASN1_Tag(type_tag | class_tag);
00109    }
00110 
00111 /*
00112 * DER_Sequence Constructor
00113 */
00114 DER_Encoder::DER_Sequence::DER_Sequence(ASN1_Tag t1, ASN1_Tag t2) :
00115    type_tag(t1), class_tag(t2)
00116    {
00117    }
00118 
00119 /*
00120 * Return the encoded contents
00121 */
00122 secure_vector<byte> DER_Encoder::get_contents()
00123    {
00124    if(subsequences.size() != 0)
00125       throw Invalid_State("DER_Encoder: Sequence hasn't been marked done");
00126 
00127    secure_vector<byte> output;
00128    std::swap(output, contents);
00129    return output;
00130    }
00131 
00132 /*
00133 * Start a new ASN.1 SEQUENCE/SET/EXPLICIT
00134 */
00135 DER_Encoder& DER_Encoder::start_cons(ASN1_Tag type_tag,
00136                                      ASN1_Tag class_tag)
00137    {
00138    subsequences.push_back(DER_Sequence(type_tag, class_tag));
00139    return (*this);
00140    }
00141 
00142 /*
00143 * Finish the current ASN.1 SEQUENCE/SET/EXPLICIT
00144 */
00145 DER_Encoder& DER_Encoder::end_cons()
00146    {
00147    if(subsequences.empty())
00148       throw Invalid_State("DER_Encoder::end_cons: No such sequence");
00149 
00150    secure_vector<byte> seq = subsequences[subsequences.size()-1].get_contents();
00151    subsequences.pop_back();
00152    raw_bytes(seq);
00153    return (*this);
00154    }
00155 
00156 /*
00157 * Start a new ASN.1 EXPLICIT encoding
00158 */
00159 DER_Encoder& DER_Encoder::start_explicit(u16bit type_no)
00160    {
00161    ASN1_Tag type_tag = static_cast<ASN1_Tag>(type_no);
00162 
00163    if(type_tag == SET)
00164       throw Internal_Error("DER_Encoder.start_explicit(SET); cannot perform");
00165 
00166    return start_cons(type_tag, CONTEXT_SPECIFIC);
00167    }
00168 
00169 /*
00170 * Finish the current ASN.1 EXPLICIT encoding
00171 */
00172 DER_Encoder& DER_Encoder::end_explicit()
00173    {
00174    return end_cons();
00175    }
00176 
00177 /*
00178 * Write raw bytes into the stream
00179 */
00180 DER_Encoder& DER_Encoder::raw_bytes(const secure_vector<byte>& val)
00181    {
00182    return raw_bytes(&val[0], val.size());
00183    }
00184 
00185 DER_Encoder& DER_Encoder::raw_bytes(const std::vector<byte>& val)
00186    {
00187    return raw_bytes(&val[0], val.size());
00188    }
00189 
00190 /*
00191 * Write raw bytes into the stream
00192 */
00193 DER_Encoder& DER_Encoder::raw_bytes(const byte bytes[], size_t length)
00194    {
00195    if(subsequences.size())
00196       subsequences[subsequences.size()-1].add_bytes(bytes, length);
00197    else
00198       contents += std::make_pair(bytes, length);
00199 
00200    return (*this);
00201    }
00202 
00203 /*
00204 * Encode a NULL object
00205 */
00206 DER_Encoder& DER_Encoder::encode_null()
00207    {
00208    return add_object(NULL_TAG, UNIVERSAL, nullptr, 0);
00209    }
00210 
00211 /*
00212 * DER encode a BOOLEAN
00213 */
00214 DER_Encoder& DER_Encoder::encode(bool is_true)
00215    {
00216    return encode(is_true, BOOLEAN, UNIVERSAL);
00217    }
00218 
00219 /*
00220 * DER encode a small INTEGER
00221 */
00222 DER_Encoder& DER_Encoder::encode(size_t n)
00223    {
00224    return encode(BigInt(n), INTEGER, UNIVERSAL);
00225    }
00226 
00227 /*
00228 * DER encode a small INTEGER
00229 */
00230 DER_Encoder& DER_Encoder::encode(const BigInt& n)
00231    {
00232    return encode(n, INTEGER, UNIVERSAL);
00233    }
00234 
00235 /*
00236 * DER encode an OCTET STRING or BIT STRING
00237 */
00238 DER_Encoder& DER_Encoder::encode(const secure_vector<byte>& bytes,
00239                                  ASN1_Tag real_type)
00240    {
00241    return encode(&bytes[0], bytes.size(),
00242                  real_type, real_type, UNIVERSAL);
00243    }
00244 
00245 /*
00246 * DER encode an OCTET STRING or BIT STRING
00247 */
00248 DER_Encoder& DER_Encoder::encode(const std::vector<byte>& bytes,
00249                                  ASN1_Tag real_type)
00250    {
00251    return encode(&bytes[0], bytes.size(),
00252                  real_type, real_type, UNIVERSAL);
00253    }
00254 
00255 /*
00256 * Encode this object
00257 */
00258 DER_Encoder& DER_Encoder::encode(const byte bytes[], size_t length,
00259                                  ASN1_Tag real_type)
00260    {
00261    return encode(bytes, length, real_type, real_type, UNIVERSAL);
00262    }
00263 
00264 /*
00265 * DER encode a BOOLEAN
00266 */
00267 DER_Encoder& DER_Encoder::encode(bool is_true,
00268                                  ASN1_Tag type_tag, ASN1_Tag class_tag)
00269    {
00270    byte val = is_true ? 0xFF : 0x00;
00271    return add_object(type_tag, class_tag, &val, 1);
00272    }
00273 
00274 /*
00275 * DER encode a small INTEGER
00276 */
00277 DER_Encoder& DER_Encoder::encode(size_t n,
00278                                  ASN1_Tag type_tag, ASN1_Tag class_tag)
00279    {
00280    return encode(BigInt(n), type_tag, class_tag);
00281    }
00282 
00283 /*
00284 * DER encode an INTEGER
00285 */
00286 DER_Encoder& DER_Encoder::encode(const BigInt& n,
00287                                  ASN1_Tag type_tag, ASN1_Tag class_tag)
00288    {
00289    if(n == 0)
00290       return add_object(type_tag, class_tag, 0);
00291 
00292    bool extra_zero = (n.bits() % 8 == 0);
00293    secure_vector<byte> contents(extra_zero + n.bytes());
00294    BigInt::encode(&contents[extra_zero], n);
00295    if(n < 0)
00296       {
00297       for(size_t i = 0; i != contents.size(); ++i)
00298          contents[i] = ~contents[i];
00299       for(size_t i = contents.size(); i > 0; --i)
00300          if(++contents[i-1])
00301             break;
00302       }
00303 
00304    return add_object(type_tag, class_tag, contents);
00305    }
00306 
00307 /*
00308 * DER encode an OCTET STRING or BIT STRING
00309 */
00310 DER_Encoder& DER_Encoder::encode(const secure_vector<byte>& bytes,
00311                                  ASN1_Tag real_type,
00312                                  ASN1_Tag type_tag, ASN1_Tag class_tag)
00313    {
00314    return encode(&bytes[0], bytes.size(),
00315                  real_type, type_tag, class_tag);
00316    }
00317 
00318 /*
00319 * DER encode an OCTET STRING or BIT STRING
00320 */
00321 DER_Encoder& DER_Encoder::encode(const std::vector<byte>& bytes,
00322                                  ASN1_Tag real_type,
00323                                  ASN1_Tag type_tag, ASN1_Tag class_tag)
00324    {
00325    return encode(&bytes[0], bytes.size(),
00326                  real_type, type_tag, class_tag);
00327    }
00328 
00329 /*
00330 * DER encode an OCTET STRING or BIT STRING
00331 */
00332 DER_Encoder& DER_Encoder::encode(const byte bytes[], size_t length,
00333                                  ASN1_Tag real_type,
00334                                  ASN1_Tag type_tag, ASN1_Tag class_tag)
00335    {
00336    if(real_type != OCTET_STRING && real_type != BIT_STRING)
00337       throw Invalid_Argument("DER_Encoder: Invalid tag for byte/bit string");
00338 
00339    if(real_type == BIT_STRING)
00340       {
00341       secure_vector<byte> encoded;
00342       encoded.push_back(0);
00343       encoded += std::make_pair(bytes, length);
00344       return add_object(type_tag, class_tag, encoded);
00345       }
00346    else
00347       return add_object(type_tag, class_tag, bytes, length);
00348    }
00349 
00350 /*
00351 * Conditionally write some values to the stream
00352 */
00353 DER_Encoder& DER_Encoder::encode_if(bool cond, DER_Encoder& codec)
00354    {
00355    if(cond)
00356       return raw_bytes(codec.get_contents());
00357    return (*this);
00358    }
00359 
00360 DER_Encoder& DER_Encoder::encode_if(bool cond, const ASN1_Object& obj)
00361    {
00362    if(cond)
00363       encode(obj);
00364    return (*this);
00365    }
00366 
00367 /*
00368 * Request for an object to encode itself
00369 */
00370 DER_Encoder& DER_Encoder::encode(const ASN1_Object& obj)
00371    {
00372    obj.encode_into(*this);
00373    return (*this);
00374    }
00375 
00376 /*
00377 * Write the encoding of the byte(s)
00378 */
00379 DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
00380                                      const byte rep[], size_t length)
00381    {
00382    secure_vector<byte> buffer;
00383    buffer += encode_tag(type_tag, class_tag);
00384    buffer += encode_length(length);
00385    buffer += std::make_pair(rep, length);
00386 
00387    return raw_bytes(buffer);
00388    }
00389 
00390 /*
00391 * Write the encoding of the byte(s)
00392 */
00393 DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
00394                                      const std::string& rep_str)
00395    {
00396    const byte* rep = reinterpret_cast<const byte*>(rep_str.data());
00397    const size_t rep_len = rep_str.size();
00398    return add_object(type_tag, class_tag, rep, rep_len);
00399    }
00400 
00401 /*
00402 * Write the encoding of the byte
00403 */
00404 DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag,
00405                                      ASN1_Tag class_tag, byte rep)
00406    {
00407    return add_object(type_tag, class_tag, &rep, 1);
00408    }
00409 
00410 }