bool SshEncryptionFacility::createAuthenticationKeyFromOpenSSL(const QByteArray &privKeyFileContents, QList<BigInt> &pubKeyParams, QList<BigInt> &allKeyParams, QString &error) { try { bool syntaxOk = true; QList<QByteArray> lines = privKeyFileContents.split('\n'); while (lines.last().isEmpty()) lines.removeLast(); if (lines.count() < 3) { syntaxOk = false; } else if (lines.first() == PrivKeyFileStartLineRsa) { if (lines.last() != PrivKeyFileEndLineRsa) syntaxOk = false; else m_authKeyAlgoName = SshCapabilities::PubKeyRsa; } else if (lines.first() == PrivKeyFileStartLineDsa) { if (lines.last() != PrivKeyFileEndLineDsa) syntaxOk = false; else m_authKeyAlgoName = SshCapabilities::PubKeyDss; } else { syntaxOk = false; } if (!syntaxOk) { error = SSH_TR("Unexpected format."); return false; } QByteArray privateKeyBlob; for (int i = 1; i < lines.size() - 1; ++i) privateKeyBlob += lines.at(i); privateKeyBlob = QByteArray::fromBase64(privateKeyBlob); BER_Decoder decoder(convertByteArray(privateKeyBlob), privateKeyBlob.size()); BER_Decoder sequence = decoder.start_cons(SEQUENCE); size_t version; sequence.decode (version); if (version != 0) { error = SSH_TR("Key encoding has version %1, expected 0.").arg(version); return false; } if (m_authKeyAlgoName == SshCapabilities::PubKeyDss) { BigInt p, q, g, y, x; sequence.decode (p).decode (q).decode (g).decode (y).decode (x); DSA_PrivateKey * const dsaKey = new DSA_PrivateKey(m_rng, DL_Group(p, q, g), x); m_authKey.reset(dsaKey); pubKeyParams << p << q << g << y; allKeyParams << pubKeyParams << x; } else { BigInt p, q, e, d, n; sequence.decode(n).decode(e).decode(d).decode(p).decode(q); RSA_PrivateKey * const rsaKey = new RSA_PrivateKey(m_rng, p, q, e, d, n); m_authKey.reset(rsaKey); pubKeyParams << e << n; allKeyParams << pubKeyParams << p << q << d; } sequence.discard_remaining(); sequence.verify_end(); } catch (const Botan::Exception &ex) { error = QLatin1String(ex.what()); return false; } catch (const Botan::Decoding_Error &ex) { error = QLatin1String(ex.what()); return false; } return true; }
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 SshEncryptionFacility::createAuthenticationKeyFromOpenSSL(const QByteArray &privKeyFileContents, QList<BigInt> &pubKeyParams, QList<BigInt> &allKeyParams, QString &error) { try { bool syntaxOk = true; QList<QByteArray> lines = privKeyFileContents.split('\n'); while (lines.last().isEmpty()) lines.removeLast(); if (lines.count() < 3) { syntaxOk = false; } else if (lines.first() == PrivKeyFileStartLineRsa) { if (lines.last() != PrivKeyFileEndLineRsa) syntaxOk = false; else m_authKeyAlgoName = SshCapabilities::PubKeyRsa; } else if (lines.first() == PrivKeyFileStartLineDsa) { if (lines.last() != PrivKeyFileEndLineDsa) syntaxOk = false; else m_authKeyAlgoName = SshCapabilities::PubKeyDss; } else if (lines.first() == PrivKeyFileStartLineEcdsa) { if (lines.last() != PrivKeyFileEndLineEcdsa) syntaxOk = false; // m_authKeyAlgoName set below, as we don't know the size yet. } else { syntaxOk = false; } if (!syntaxOk) { error = SSH_TR("Unexpected format."); return false; } QByteArray privateKeyBlob; for (int i = 1; i < lines.size() - 1; ++i) privateKeyBlob += lines.at(i); privateKeyBlob = QByteArray::fromBase64(privateKeyBlob); BER_Decoder decoder(convertByteArray(privateKeyBlob), privateKeyBlob.size()); BER_Decoder sequence = decoder.start_cons(SEQUENCE); size_t version; sequence.decode (version); const size_t expectedVersion = m_authKeyAlgoName.isEmpty() ? 1 : 0; if (version != expectedVersion) { error = SSH_TR("Key encoding has version %1, expected %2.") .arg(version).arg(expectedVersion); return false; } if (m_authKeyAlgoName == SshCapabilities::PubKeyDss) { BigInt p, q, g, y, x; sequence.decode (p).decode (q).decode (g).decode (y).decode (x); DSA_PrivateKey * const dsaKey = new DSA_PrivateKey(m_rng, DL_Group(p, q, g), x); m_authKey.reset(dsaKey); pubKeyParams << p << q << g << y; allKeyParams << pubKeyParams << x; } else if (m_authKeyAlgoName == SshCapabilities::PubKeyRsa) { BigInt p, q, e, d, n; sequence.decode(n).decode(e).decode(d).decode(p).decode(q); RSA_PrivateKey * const rsaKey = new RSA_PrivateKey(m_rng, p, q, e, d, n); m_authKey.reset(rsaKey); pubKeyParams << e << n; allKeyParams << pubKeyParams << p << q << d; } else { BigInt privKey; sequence.decode_octet_string_bigint(privKey); m_authKeyAlgoName = SshCapabilities::ecdsaPubKeyAlgoForKeyWidth( static_cast<int>(privKey.bytes())); const EC_Group group(SshCapabilities::oid(m_authKeyAlgoName)); auto * const key = new ECDSA_PrivateKey(m_rng, group, privKey); m_authKey.reset(key); pubKeyParams << key->public_point().get_affine_x() << key->public_point().get_affine_y(); allKeyParams << pubKeyParams << privKey; } sequence.discard_remaining(); sequence.verify_end(); } catch (const Exception &ex) { error = QLatin1String(ex.what()); return false; } catch (const Decoding_Error &ex) { error = QLatin1String(ex.what()); return false; } 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; }