/** * @param fallbackResolver The {@link PublicKeyEntryResolver} to consult if none of the built-in * ones can be used. If {@code null} and no built-in resolver can be used then an {@link * InvalidKeySpecException} is thrown. * @return The resolved {@link PublicKey} - or {@code null} if could not be resolved. <B>Note:</B> * may be called only after key type and data bytes have been set or exception(s) may be * thrown * @throws IOException If failed to decode the key * @throws GeneralSecurityException If failed to generate the key */ public PublicKey resolvePublicKey(PublicKeyEntryResolver fallbackResolver) throws IOException, GeneralSecurityException { String kt = getKeyType(); PublicKeyEntryResolver decoder = KeyUtils.getPublicKeyEntryDecoder(kt); if (decoder == null) { decoder = fallbackResolver; } if (decoder == null) { throw new InvalidKeySpecException("No decoder available for key type=" + kt); } return decoder.resolve(kt, getKeyData()); }
/** * Encodes a public key data the same way as the {@link #parsePublicKeyEntry(String)} expects it * * @param <A> The generic appendable class * @param sb The {@link Appendable} instance to encode the data into * @param key The {@link PublicKey} - ignored if {@code null} * @return The updated appendable instance * @throws IOException If failed to append the data */ public static <A extends Appendable> A appendPublicKeyEntry(A sb, PublicKey key) throws IOException { if (key == null) { return sb; } @SuppressWarnings("unchecked") PublicKeyEntryDecoder<PublicKey, ?> decoder = (PublicKeyEntryDecoder<PublicKey, ?>) KeyUtils.getPublicKeyEntryDecoder(key); if (decoder == null) { throw new StreamCorruptedException("Cannot retrieve decoder for key=" + key.getAlgorithm()); } try (ByteArrayOutputStream s = new ByteArrayOutputStream(Byte.MAX_VALUE)) { String keyType = decoder.encodePublicKey(s, key); byte[] bytes = s.toByteArray(); String b64Data = Base64.encodeToString(bytes); sb.append(keyType).append(' ').append(b64Data); } return sb; }