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 List<CertificateDecoder> getCertificateDecoders() { return Arrays.asList(new DsaCertificateDecoder(), new OpenSshCertificateDecoder(getKeyFormat()) { @Override KeyPair generateKeyPair(TypesReader typesReader) throws GeneralSecurityException, IOException { BigInteger p = typesReader.readMPINT(); BigInteger q = typesReader.readMPINT(); BigInteger g = typesReader.readMPINT(); BigInteger y = typesReader.readMPINT(); BigInteger x = typesReader.readMPINT(); DSAPrivateKeySpec privateKeySpec = new DSAPrivateKeySpec(x, p, q, g); DSAPublicKeySpec publicKeySpec = new DSAPublicKeySpec(y, p, q, g); KeyFactory factory = KeyFactory.getInstance("DSA"); PrivateKey privateKey = factory.generatePrivate(privateKeySpec); PublicKey publicKey = factory.generatePublic(publicKeySpec); return new KeyPair(publicKey, privateKey); } }); }
@Override public byte[] encodeSignature(byte[] signature) throws IOException { TypesWriter tw = new TypesWriter(); tw.writeString(getKeyFormat()); int index = 3; int len = signature[index++] & 0xff; byte[] r = new byte[len]; System.arraycopy(signature, index, r, 0, r.length); index += len + 1; len = signature[index++] & 0xff; byte[] s = new byte[len]; System.arraycopy(signature, index, s, 0, s.length); byte[] a40 = new byte[40]; /* Patch (unsigned) r and s into the target array. */ int r_copylen = (r.length < 20) ? r.length : 20; int s_copylen = (s.length < 20) ? s.length : 20; System.arraycopy(r, r.length - r_copylen, a40, 20 - r_copylen, r_copylen); System.arraycopy(s, s.length - s_copylen, a40, 40 - s_copylen, s_copylen); tw.writeString(a40, 0, 40); return tw.getBytes(); }
if (!sig_format.equals(getKeyFormat())) throw new IOException("Peer sent wrong signature format");
@Override public DSAPublicKey decodePublicKey(byte[] encodedPublicKey) throws IOException { TypesReader tr = new TypesReader(encodedPublicKey); String key_format = tr.readString(); if (!key_format.equals(getKeyFormat())) { throw new IOWarningException("Unsupported key format found '" + key_format + "' while expecting " + getKeyFormat()); } final BigInteger p = tr.readMPINT(); final BigInteger q = tr.readMPINT(); final BigInteger g = tr.readMPINT(); final BigInteger y = tr.readMPINT(); if (tr.remain() != 0) { throw new IOException("Padding in DSA public key!"); } try { KeyFactory generator = KeyFactory.getInstance("DSA"); return (DSAPublicKey) generator.generatePublic(new DSAPublicKeySpec(y, p, q, g)); } catch (GeneralSecurityException ex) { throw new IOException("Could not generate DSA Key", ex); } }
@Override public byte[] encodePublicKey(DSAPublicKey publicKey) throws IOException { DSAParams params = publicKey.getParams(); TypesWriter tw = new TypesWriter(); tw.writeString(getKeyFormat()); tw.writeMPInt(params.getP()); tw.writeMPInt(params.getQ()); tw.writeMPInt(params.getG()); tw.writeMPInt(publicKey.getY()); return tw.getBytes(); }