botan
botan copied to clipboard
Can we decode BER encoded using botan?
Can you please help us understand how we can decode the multiple hierarchies
for example, if we have the following
SEQUENCE : SEQUENCE : SET : SEQUENCE : OBJECT IDENTIFIER : countryName [2.5.4.6] PRINTABLE STRING : 'US' SET : SEQUENCE : OBJECT IDENTIFIER : organizationName [2.5.4.10] PRINTABLE STRING : 'ABCD' SET : SEQUENCE : OBJECT IDENTIFIER : commonName [2.5.4.3] PRINTABLE STRING : 'ABCD Root' INTEGER : 223338299393
Can we do decode this using Botan? Also, if we encode the sample mentioned in https://github.com/randombit/botan/issues/1684 Can we decode using botan?
You can use BER_Decoder for decoding and you can see multiple examples of how it's used to decode X.509 objects here.
On that note, what you want to decode there looks a bit like X.509. Have you seen Botan's API for that? Maybe you don't have to implement custom decoding logic.
Actually tried using the BER_DECODER but couldn't succeed
Let's take an example here... I am generating a random number and encoding it with an OID. Same random number to be decoded back
Following is sample:
_std::vector<uint8_t> randomNewNumber(16);
Botan::AutoSeeded_RNG rngl;
rngl.randomize(randomNewNumber.data(), 16);
Botan::secure_vector<uint8_t> signedData = Botan::DER_Encoder()
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.encode(Botan::OID("1.2.840.113549.1.9.25.3"))
.start_cons(Botan::ASN1_Tag::SET)
.encode(randomNewNumber, Botan::ASN1_Tag::OCTET_STRING)
.end_cons()
.end_cons()
.get_contents();
std::vector<uint8_t> randomNumberDEREncoded = Botan::unlock(signedData);
Botan::BER_Decoder dec(randomNumberDEREncoded);
dec.decode(randomNumberDEREncoded,Botan::SEQUENCE);_
Here decoding failed with Bad_Tag, I understand that SEQUENCE would not be the correct input here in decode. Can you please guide how can we decode this?
You can use the decoder analogously to the encoder. For your example above:
// ...
std::vector<uint8_t> randomNumberDEREncoded = Botan::unlock(signedData);
Botan::OID oid;
std::vector<uint8_t> rand;
Botan::BER_Decoder(randomNumberDEREncoded)
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.decode(oid)
.start_cons(Botan::ASN1_Tag::SET)
.decode(rand, Botan::ASN1_Tag::OCTET_STRING)
.end_cons()
.end_cons();
assert(randomNewNumber == rand);
Thank you for sharing the sample code.
Can you please share the sample example link as well which you mentioned above? Also, do we have any example to use the CONTEXT_SPECIFIC as well?
you please share the sample example link as well which you mentioned above
I'm not sure which link you are referring to. I linked https://github.com/randombit/botan/blob/a19627a2b76e7f1b9b7e19fbaf2ef464ac220ce6/src/lib/x509/x509_obj.cpp above.
example to use the CONTEXT_SPECIFIC as well
You can look for uses of ASN1_Class::ContextSpecific
in the code base.
Side note: are you absolutely sure that the existing X.509 API in Botan is not what you need? What is it you're trying to encode/decode?
As per my requirement, I have a few keys and other data appended along with the certificate data which is to be decoded.
Further tried using the sample but faced Invalid Argument while encoding and Bad_Tag issue while decoding one sample.
Tried the following to Encode:
std::vector<uint8_t> CountryCode = Botan::hex_decode("5553"); Botan::secure_vector<uint8_t> signedDataSample = Botan::DER_Encoder() .start_cons(Botan::ASN1_Tag::SEQUENCE) .start_cons(Botan::ASN1_Tag::SEQUENCE) .start_cons(Botan::ASN1_Tag::SET) .start_cons(Botan::ASN1_Tag::SEQUENCE) .encode(Botan::OID("2.5.4.6")) .encode( CountryCode, Botan::ASN1_Tag::PRINTABLE_STRING) .end_cons() .end_cons() .end_cons() .end_cons() .get_contents();
But it gives an invalid argument exception. Can you please mention, what wrong we are doing here.
I have a sample encoded string "3048303F310B300906035504061302555331153013060355040A130C555555555553616D706C65733119301706035504031310555555552053616D706C6520526F6F7402053400000006"
For which I am trying to use the below
Botan::BER_Decoder(Botan::hex_decode("3048303F310B300906035504061302555331153013060355040A130C555555555553616D706C65733119301706035504031310555555552053616D706C6520526F6F7402053400000006"))
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.start_cons(Botan::ASN1_Tag::SET)
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.decode(oid1)
.decode(CountryCode2, Botan::ASN1_Tag::PRINTABLE_STRING)
.end_cons()
.end_cons()
.start_cons(Botan::ASN1_Tag::SET)
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.decode(oid2)
.decode(Issuer, Botan::ASN1_Tag::PRINTABLE_STRING)
.end_cons()
.end_cons()
.start_cons(Botan::ASN1_Tag::SET)
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.decode(oid3)
.decode(SerialNum, Botan::ASN1_Tag::PRINTABLE_STRING)
.end_cons()
.end_cons()
.end_cons()
.decode_integer_type(num)
.end_cons();
Hi, which of the instructions above throws the exception? I assume it's one of the decode
s? Maybe you can look up under which circumstances decode
throws the exception you get.
Firstly, While encoding the following,
std::vector<uint8_t> CountryCode = Botan::hex_decode("5553");
Botan::secure_vector<uint8_t> signedDataSample = Botan::DER_Encoder()
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.start_cons(Botan::ASN1_Tag::SET)
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.encode(Botan::OID("2.5.4.6"))
.encode( CountryCode, Botan::ASN1_Tag::PRINTABLE_STRING)
.end_cons()
.end_cons()
.end_cons()
.end_cons()
.get_contents();
getting exception : Microsoft C++ exception: Botan::Invalid_Argument on instruction .encode( CountryCode, Botan::ASN1_Tag::PRINTABLE_STRING)
Secondly, when trying to decode one available sequence i.e. "3048303F310B300906035504061302555331153013060355040A130C555555555553616D706C65733119301706035504031310555555552053616D706C6520526F6F7402053400000006"
Botan::BER_Decoder(Botan::hex_decode("3048303F310B300906035504061302555331153013060355040A130C555555555553616D706C65733119301706035504031310555555552053616D706C6520526F6F7402053400000006"))
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.start_cons(Botan::ASN1_Tag::SET)
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.decode(oid1)
.decode(CountryCode2, Botan::ASN1_Tag::PRINTABLE_STRING)
.end_cons()
.end_cons()
.start_cons(Botan::ASN1_Tag::SET)
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.decode(oid2)
.decode(Issuer, Botan::ASN1_Tag::PRINTABLE_STRING)
.end_cons()
.end_cons()
.start_cons(Botan::ASN1_Tag::SET)
.start_cons(Botan::ASN1_Tag::SEQUENCE)
.decode(oid3)
.decode(SerialNum, Botan::ASN1_Tag::PRINTABLE_STRING)
.end_cons()
.end_cons()
.end_cons()
.decode_integer_type(num)
.end_cons();
getting exception : Microsoft C++ exception: Botan::BER_Bad_Tag at instruction .decode(CountryCode2, Botan::ASN1_Tag::PRINTABLE_STRING)
Ah, the problem seems to be that you need to decode the printable string into a Botan::ASN1_String
, rather than a plain vector.
Hi hrantzsch
Thank you for correcting the type mentioned above. I am able to decode now.
Only one issue still persists, w.r.t context specific.
Decoding a sample - "8081885332A1F84521DE2D3B23EBE3CB2D674B16114EC598214102C3DEE175C2A669400EB039136E632E4A32140AAB5546AC478799F7B7A025335F45CCA3CD1894314FF513E3E02573ADB5135DF8B1DB3277D9DE273DC6A8B5E79D215F63B93A52137DBAFBE5CC3FF472919D86D2409762370FA80A77AED183E1ED597BF9BFDC9D286934C7C1E1E8D003FB"
I have trying to decode with the below instruction
std::vector<uint8_t> ContextString1; .decode(ContextString1, Botan::ASN1_Tag::BIT_STRING, Botan::ASN1_Tag::BIT_STRING, Botan::ASN1_Tag::CONTEXT_SPECIFIC)
Here i have tried Octet String, Bit String and plain vector, but did not helped much. Can you please mention how we can do that with Botan?
Botan::ASN1_String contextString;
// ...
.decode(contextString, Botan::ASN1_Tag::PRINTABLE_STRING)
~~should work :)~~
Edit: sorry, I think I misread your question. You can find example usages of CONTEXT_SPECIFIC
decoding in src/lib/x509/ocsp.cpp
. Can you have a look at those and see if they help you?
Hi hrantzsch
Tried options from the above mentioned src/lib/x509/ocsp.cpp, where cotext_Specific is used in decoding the optional parameters It did not help further, If you can have a look, it will be great
Thanks
decode(ContextString1, Botan::OCTET_STRING, Botan::UNIVERSAL, Botan::CONTEXT_SPECIFIC);
Does this work for you?
Yes, it worked for me. Thanks a lot. Do you have any documentation which explains all ways to use it?
Unfortunately not, as far as I know.