tomitribe / http-signatures-java

Java Client Library for HTTP Signatures
Apache License 2.0
86 stars 39 forks source link

PEM.java fails with NPE if certificate file is of type BEGIN ENCRYPTED PRIVATE KEY #44

Open kingsfleet opened 4 years ago

kingsfleet commented 4 years ago

In this case object.getPEMObjectType will return null, causing a NPE in the case statement.

public static PrivateKey readPrivateKey(final InputStream is) throws InvalidKeySpecException, IOException {

       final List<PEMObject> objects = readPEMObjects(is);
        for (final PEMObject object : objects) {
            switch (object.getPEMObjectType()) {
                case PRIVATE_KEY_PKCS1:
                    return RSA.privateKeyFromPKCS1(object.getDerBytes());
                case PRIVATE_EC_KEY_PKCS8:
                    return EC.privateKeyFromPKCS8(object.getDerBytes());
                case PRIVATE_KEY_PKCS8:
                    try {
                        return RSA.privateKeyFromPKCS8(object.getDerBytes());
                    } catch (InvalidKeySpecException e) {
                        return EC.privateKeyFromPKCS8(object.getDerBytes());
                    }
                default:
                    break;
            }
        }
        throw new IllegalArgumentException("Found no private key");
    }

perhaps:

Stream.of(readPEMObjects(is))
   .map(PEMObject:getPEMObjectType)
   .filter(Objects::nonNull)
   .flatMap(PEM:parsePemObject)
   .findFirst().orElseThrow(() -> throw new IllegalArgumentException("Found no private key"));

private static Stream<PrivateKey> parsePemObject(PEMObject object) {
   PrivateKey found;
    switch (object.getPEMObjectType()) {
                case PRIVATE_KEY_PKCS1:
                    found = RSA.privateKeyFromPKCS1(object.getDerBytes());
                case PRIVATE_EC_KEY_PKCS8:
                    found = EC.privateKeyFromPKCS8(object.getDerBytes());
                case PRIVATE_KEY_PKCS8:
                    try {
                        found = RSA.privateKeyFromPKCS8(object.getDerBytes());
                    } catch (InvalidKeySpecException e) {
                        found = EC.privateKeyFromPKCS8(object.getDerBytes());
                    }
                default:
                    break;
            }
   return Optional.ofNullable(found).map(Stream::of).orElseGet(Stream::empty);
}
jeanouii commented 4 years ago

Looks like a good improvement. Would you like to create a PR for it?