@Override public String getInjectedKey() throws IOException { InstanceIdentity id = InstanceIdentity.get(); return "ssh-rsa " + encode(new RSAKeyAlgorithm().encodePublicKey(id.getPublic())); }
@Override public RSAPublicKey decodePublicKey(byte[] encodedPublicKey) throws IOException { final TypesReader tr = new TypesReader(encodedPublicKey); final String key_format = tr.readString(); if (!key_format.equals(getKeyFormat())) { throw new IOWarningException("Unsupported key format found '" + key_format + "' while expecting " + getKeyFormat()); } final BigInteger e = tr.readMPINT(); final BigInteger n = tr.readMPINT(); if (tr.remain() != 0) { throw new IOException("Padding in RSA public key!"); } try { final KeyFactory generator = KeyFactory.getInstance("RSA"); return (RSAPublicKey) generator.generatePublic(new RSAPublicKeySpec(n, e)); } catch (GeneralSecurityException ex) { throw new IOException("Could not generate RSA key", ex); } }
private static Collection<KeyAlgorithm<PublicKey, PrivateKey>> buildSupportAlgorithmsList() { List<KeyAlgorithm<?, ?>> algorithms = new ArrayList<>(); algorithms.add(new ED25519KeyAlgorithm()); try { KeyFactory.getInstance("EC"); algorithms.add(new ECDSAKeyAlgorithm.ECDSASha2Nistp521()); algorithms.add(new ECDSAKeyAlgorithm.ECDSASha2Nistp384()); algorithms.add(new ECDSAKeyAlgorithm.ECDSASha2Nistp256()); } catch (GeneralSecurityException ex) { // we don't use ECDSA algorithms in this case } algorithms.add(new RSAKeyAlgorithm()); algorithms.add(new DSAKeyAlgorithm()); return (Collection) Collections.unmodifiableCollection(algorithms); } }
@Override public byte[] decodeSignature(byte[] encodedSignature) throws IOException { final TypesReader tr = new TypesReader(encodedSignature); final String sig_format = tr.readString(); if (!sig_format.equals(getKeyFormat())) { throw new IOException("Peer sent wrong signature format"); } /* S is NOT an MPINT. "The value for 'rsa_signature_blob' is encoded as a string * containing s (which is an integer, without lengths or padding, unsigned and in * network byte order)." See also below. */ final byte[] s = tr.readByteString(); if (s.length == 0) { throw new IOException("Error in RSA signature, S is empty."); } if (tr.remain() != 0) { throw new IOException("Padding in RSA signature!"); } return s; }
@Override public byte[] encodePublicKey(RSAPublicKey publicKey) throws IOException { final TypesWriter tw = new TypesWriter(); tw.writeString(getKeyFormat()); tw.writeMPInt(publicKey.getPublicExponent()); tw.writeMPInt(publicKey.getModulus()); return tw.getBytes(); }
@Override public byte[] encodeSignature(byte[] signature) throws IOException { final TypesWriter tw = new TypesWriter(); tw.writeString(getKeyFormat()); /* S is NOT an MPINT. "The value for 'rsa_signature_blob' is encoded as a string * containing s (which is an integer, without lengths or padding, unsigned and in * network byte order)." */ /* Remove first zero sign byte, if present */ if ((signature.length > 1) && (signature[0] == 0x00)) { tw.writeString(signature, 1, signature.length - 1); } else { tw.writeString(signature, 0, signature.length); } return tw.getBytes(); }