Skip to content

Commit

Permalink
Validate key expiration time
Browse files Browse the repository at this point in the history
fix #7
  • Loading branch information
slawekjaranowski committed Dec 30, 2020
1 parent 3f737d6 commit 7fee01d
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package org.simplify4u.plugins.sign.openpgp;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Optional;
Expand Down Expand Up @@ -45,7 +47,7 @@ private PGPSecretKeyUtils() {
* @return keyId in hex format
*/
public static String getKeyId(PGPSecretKey secretKey) {
return String.format("%016X", secretKey.getKeyID());
return String.format("0x%016X", secretKey.getKeyID());
}

/**
Expand Down Expand Up @@ -133,4 +135,30 @@ private static String fingerprintToString(byte[] bytes) {
}
return ret.toString();
}

/**
* Verify expiration time of secret key.
*
* @param secretKey a key to check
* @param secretKeyRing a keyRing used for prepare message
*
* @throws PGPSignerException if key expired
*/
public static void verifyKeyExpiration(PGPSecretKey secretKey, PGPSecretKeyRing secretKeyRing) {

long validSeconds = secretKey.getPublicKey().getValidSeconds();
if (validSeconds > 0) {

LocalDateTime expireDateTime = secretKey.getPublicKey().getCreationTime()
.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
.plusSeconds(validSeconds);

if (LocalDateTime.now().isAfter(expireDateTime)) {
throw new PGPSignerException(keyIdDescription(secretKey, secretKeyRing)
+ " was expired at: " + expireDateTime);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import static org.simplify4u.plugins.sign.openpgp.PGPSecretKeyUtils.getKeyId;
import static org.simplify4u.plugins.sign.openpgp.PGPSecretKeyUtils.getUserIDs;
import static org.simplify4u.plugins.sign.openpgp.PGPSecretKeyUtils.keyIdDescription;
import static org.simplify4u.plugins.sign.openpgp.PGPSecretKeyUtils.verifyKeyExpiration;

import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.bcpg.ArmoredOutputStream;
Expand Down Expand Up @@ -133,6 +134,8 @@ private void loadKey() throws IOException, PGPException {
throw new PGPSignerException("Private key not found for keyId: " + getKeyId(secretKey));
}

verifyKeyExpiration(secretKey, secretKeyRing);

pgpPrivateKey = secretKey
.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().build(pgpKeyInfo.getPass()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
package org.simplify4u.plugins.sign.openpgp;

import java.io.File;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
Expand Down Expand Up @@ -99,7 +103,7 @@ void loadSubKeyWithMasterKey() throws PGPSignerException {
// when
assertThatThrownBy(() -> pgpSigner.setKeyInfo(keyInfo))
.isExactlyInstanceOf(PGPSignerException.class)
.hasMessage("Private key not found for keyId: 0C5CEA1C96038404");
.hasMessage("Private key not found for keyId: 0x0C5CEA1C96038404");
}

@Test
Expand Down Expand Up @@ -150,4 +154,45 @@ void requireInvalidPassThrowException() throws PGPSignerException {
.hasMessage("org.bouncycastle.openpgp.PGPException: checksum mismatch at 0 of 20");
}

@Test
void expiredMasterKeyThrewException() {

// given
LocalDateTime expiredDateTime = ZonedDateTime.of(2020, 12, 23, 7, 29, 20, 0, ZoneOffset.UTC)
.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();

PGPKeyInfo keyInfo = PGPKeyInfo.builder()
.keyId("B09391374A115DE2")
.keyFile(new File(getClass().getResource("/priv-expired-key-no-pass.asc").getFile()))
.build();

assertThatThrownBy(() -> pgpSigner.setKeyInfo(keyInfo))
.isExactlyInstanceOf(PGPSignerException.class)
.hasNoCause()
.hasMessage("KeyId: 0xE82078BE6F6368CB593C47C5B09391374A115DE2 was expired at: " + expiredDateTime);
}

@Test
void expiredSubKeyThrewException() {

// given
LocalDateTime expiredDateTime = ZonedDateTime.of(2020, 12, 23, 7, 30, 13, 0, ZoneOffset.UTC)
.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();

PGPKeyInfo keyInfo = PGPKeyInfo.builder()
.keyId("44A920F7DCC8A31E")
.keyFile(new File(getClass().getResource("/priv-expired-key-no-pass.asc").getFile()))
.build();

assertThatThrownBy(() -> pgpSigner.setKeyInfo(keyInfo))
.isExactlyInstanceOf(PGPSignerException.class)
.hasNoCause()
.hasMessage("SubKeyId: 0x44A920F7DCC8A31E of 0xE82078BE6F6368CB593C47C5B09391374A115DE2 was expired at: "
+ expiredDateTime);
}

}

0 comments on commit 7fee01d

Please sign in to comment.