/* * Decode a BER encoded DistinguishedName */ void X509_DN::decode_from(BER_Decoder& source) { MemoryVector<byte> bits; source.start_cons(SEQUENCE) .raw_bytes(bits) .end_cons(); BER_Decoder sequence(bits); while(sequence.more_items()) { BER_Decoder rdn = sequence.start_cons(SET); while(rdn.more_items()) { OID oid; ASN1_String str; rdn.start_cons(SEQUENCE) .decode(oid) .decode(str) .verify_end() .end_cons(); add_attribute(oid, str.value()); } } dn_bits = bits; }
/* * Decompress a message */ void CMS_Decoder::decompress(BER_Decoder& decoder) { size_t version; AlgorithmIdentifier comp_algo; BER_Decoder comp_info = decoder.start_cons(SEQUENCE); comp_info.decode(version); if(version != 0) throw Decoding_Error("CMS: Unknown version for CompressedData"); comp_info.decode(comp_algo); read_econtent(comp_info); comp_info.end_cons(); Filter* decompressor = 0; info = comp_algo.oid.as_string(); #if defined(BOTAN_HAS_COMPRESSOR_ZLIB) if(comp_algo.oid == OIDS::lookup("Compression.Zlib")) { decompressor = new Zlib_Decompression; info = "Zlib"; } #endif if(!decompressor) status = FAILURE; Pipe pipe(decompressor); pipe.process_msg(data); data = pipe.read_all(); }
/* * Decode a BER encoded AlgorithmIdentifier */ void AlgorithmIdentifier::decode_from(BER_Decoder& codec) { codec.start_cons(SEQUENCE) .decode(oid) .raw_bytes(parameters) .end_cons(); }
/* * Decode a BER encoded CRL_Entry */ void CRL_Entry::decode_from(BER_Decoder& source) { BigInt serial_number_bn; std::unique_ptr<CRL_Entry_Data> data(new CRL_Entry_Data); BER_Decoder entry = source.start_cons(SEQUENCE); entry.decode(serial_number_bn).decode(data->m_time); data->m_serial = BigInt::encode(serial_number_bn); if(entry.more_items()) { entry.decode(data->m_extensions); if(auto ext = data->m_extensions.get_extension_object_as<Cert_Extension::CRL_ReasonCode>()) { data->m_reason = ext->get_reason(); } else { data->m_reason = UNSPECIFIED; } } entry.end_cons(); m_data.reset(data.release()); }
/* * Decode a BER encoded Attribute */ void Attribute::decode_from(BER_Decoder& codec) { codec.start_cons(SEQUENCE) .decode(oid) .start_cons(SET) .raw_bytes(parameters) .end_cons() .end_cons(); }
Response::Response(const uint8_t response_bits[], size_t response_bits_len) : m_response_bits(response_bits, response_bits + response_bits_len) { m_dummy_response_status = Certificate_Status_Code::OCSP_RESPONSE_INVALID; BER_Decoder response_outer = BER_Decoder(m_response_bits).start_cons(SEQUENCE); size_t resp_status = 0; response_outer.decode(resp_status, ENUMERATED, UNIVERSAL); if(resp_status != 0) throw Exception("OCSP response status " + std::to_string(resp_status)); if(response_outer.more_items()) { BER_Decoder response_bytes = response_outer.start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC).start_cons(SEQUENCE); response_bytes.decode_and_check(OID("1.3.6.1.5.5.7.48.1.1"), "Unknown response type in OCSP response"); BER_Decoder basicresponse = BER_Decoder(response_bytes.get_next_octet_string()).start_cons(SEQUENCE); basicresponse.start_cons(SEQUENCE) .raw_bytes(m_tbs_bits) .end_cons() .decode(m_sig_algo) .decode(m_signature, BIT_STRING); decode_optional_list(basicresponse, ASN1_Tag(0), m_certs); size_t responsedata_version = 0; Extensions extensions; BER_Decoder(m_tbs_bits) .decode_optional(responsedata_version, ASN1_Tag(0), ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) .decode_optional(m_signer_name, ASN1_Tag(1), ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) .decode_optional_string(m_key_hash, OCTET_STRING, 2, ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) .decode(m_produced_at) .decode_list(m_responses) .decode_optional(extensions, ASN1_Tag(1), ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)); } response_outer.end_cons(); }
/* * Read a BER encoded X.509 object */ void X509_Object::decode_from(BER_Decoder& from) { from.start_cons(SEQUENCE) .start_cons(SEQUENCE) .raw_bytes(m_tbs_bits) .end_cons() .decode(m_sig_algo) .decode(m_sig, BIT_STRING) .verify_end() .end_cons(); }
/* * Decode a BER encoded CRL_Entry */ void CRL_Entry::decode_from(BER_Decoder& source) { BigInt serial_number_bn; source.start_cons(SEQUENCE) .decode(serial_number_bn) .decode(time); if(source.more_items()) { Extensions extensions(throw_on_unknown_critical); source.decode(extensions); Data_Store info; extensions.contents_to(info, info); reason = CRL_Code(info.get1_u32bit("X509v3.CRLReasonCode")); } serial = BigInt::encode(serial_number_bn); }
Response::Response(const Certificate_Store& trusted_roots, const std::vector<byte>& response_bits) { BER_Decoder response_outer = BER_Decoder(response_bits).start_cons(SEQUENCE); size_t resp_status = 0; response_outer.decode(resp_status, ENUMERATED, UNIVERSAL); if(resp_status != 0) throw std::runtime_error("OCSP response status " + std::to_string(resp_status)); if(response_outer.more_items()) { BER_Decoder response_bytes = response_outer.start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC).start_cons(SEQUENCE); response_bytes.decode_and_check(OID("1.3.6.1.5.5.7.48.1.1"), "Unknown response type in OCSP response"); BER_Decoder basicresponse = BER_Decoder(response_bytes.get_next_octet_string()).start_cons(SEQUENCE); std::vector<byte> tbs_bits; AlgorithmIdentifier sig_algo; std::vector<byte> signature; std::vector<X509_Certificate> certs; basicresponse.start_cons(SEQUENCE) .raw_bytes(tbs_bits) .end_cons() .decode(sig_algo) .decode(signature, BIT_STRING); decode_optional_list(basicresponse, ASN1_Tag(0), certs); size_t responsedata_version = 0; X509_DN name; std::vector<byte> key_hash; X509_Time produced_at; Extensions extensions; BER_Decoder(tbs_bits) .decode_optional(responsedata_version, ASN1_Tag(0), ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) .decode_optional(name, ASN1_Tag(1), ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) .decode_optional_string(key_hash, OCTET_STRING, 2, ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) .decode(produced_at) .decode_list(m_responses) .decode_optional(extensions, ASN1_Tag(1), ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)); if(certs.empty()) { if(auto cert = trusted_roots.find_cert(name, std::vector<byte>())) certs.push_back(*cert); else throw std::runtime_error("Could not find certificate that signed OCSP response"); } check_signature(tbs_bits, sig_algo, signature, trusted_roots, certs); } response_outer.end_cons(); }
bool ne7ssh_keys::getRSAKeys (char* buffer, uint32 size) { const char* headerRSA = "-----BEGIN RSA PRIVATE KEY-----\n"; const char* footerRSA = "-----END RSA PRIVATE KEY-----\n"; SecureVector<Botan::byte> keyDataRaw; BigInt p, q, e, d, n; char *start; uint32 version; start = buffer + strlen(headerRSA); Pipe base64dec (new Base64_Decoder); base64dec.process_msg ((Botan::byte*)start, size - strlen(footerRSA) - strlen(headerRSA)); keyDataRaw = base64dec.read_all (PIPE_DEFAULT_MESSAGE); BER_Decoder decoder (keyDataRaw); #if BOTAN_PRE_15 BER_Decoder sequence = BER::get_subsequence(decoder); BER::decode (sequence, version); #else BER_Decoder sequence = decoder.start_cons(SEQUENCE); sequence.decode (version); #endif if (version) { ne7ssh::errors()->push (-1, "Encountered unknown RSA key version."); return false; } #if BOTAN_PRE_15 BER::decode (sequence, n); BER::decode (sequence, e); BER::decode (sequence, d); BER::decode (sequence, p); BER::decode (sequence, q); #else sequence.decode (n); sequence.decode (e); sequence.decode (d); sequence.decode (p); sequence.decode (q); #endif sequence.discard_remaining(); sequence.verify_end(); if (n.is_zero() || e.is_zero() || d.is_zero() || p.is_zero() || q.is_zero()) { ne7ssh::errors()->push (-1, "Could not decode the supplied RSA key."); return false; } #if BOTAN_PRE_18 || BOTAN_PRE_15 rsaPrivateKey = new RSA_PrivateKey (p, q, e, d, n); #else rsaPrivateKey = new RSA_PrivateKey (*ne7ssh::rng, p, q, e, d, n); #endif publicKeyBlob.clear(); publicKeyBlob.addString ("ssh-rsa"); publicKeyBlob.addBigInt (e); publicKeyBlob.addBigInt (n); return true; }
bool ne7ssh_keys::getDSAKeys (char* buffer, uint32 size) { // DataSource_Memory privKeyPEMSrc (privKeyPEMStr); const char* headerDSA = "-----BEGIN DSA PRIVATE KEY-----\n"; const char* footerDSA = "-----END DSA PRIVATE KEY-----\n"; SecureVector<Botan::byte> keyDataRaw; BigInt p, q, g, y, x; char *start; uint32 version; start = buffer + strlen(headerDSA); Pipe base64dec (new Base64_Decoder); base64dec.process_msg ((Botan::byte*)start, size - strlen(footerDSA) - strlen(headerDSA)); keyDataRaw = base64dec.read_all (PIPE_DEFAULT_MESSAGE); BER_Decoder decoder (keyDataRaw); #if BOTAN_PRE_15 BER_Decoder sequence = BER::get_subsequence(decoder); BER::decode (sequence, version); #else BER_Decoder sequence = decoder.start_cons (SEQUENCE); sequence.decode (version); #endif if (version) { ne7ssh::errors()->push (-1, "Encountered unknown DSA key version."); return false; } #if BOTAN_PRE_15 BER::decode (sequence, p); BER::decode (sequence, q); BER::decode (sequence, g); BER::decode (sequence, y); BER::decode (sequence, x); #else sequence.decode (p); sequence.decode (q); sequence.decode (g); sequence.decode (y); sequence.decode (x); #endif sequence.discard_remaining(); sequence.verify_end(); if (p.is_zero() || q.is_zero() || g.is_zero() || y.is_zero() || x.is_zero()) { ne7ssh::errors()->push (-1, "Could not decode the supplied DSA key."); return false; } DL_Group dsaGroup (p, q, g); #if BOTAN_PRE_18 || BOTAN_PRE_15 dsaPrivateKey = new DSA_PrivateKey (dsaGroup, x); #else dsaPrivateKey = new DSA_PrivateKey (*ne7ssh::rng, dsaGroup, x); #endif publicKeyBlob.clear(); publicKeyBlob.addString ("ssh-dss"); publicKeyBlob.addBigInt (p); publicKeyBlob.addBigInt (q); publicKeyBlob.addBigInt (g); publicKeyBlob.addBigInt (y); return true; }