in org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgSignatureVerifier.java [141:281]
public SignatureVerification verify(byte[] data, byte[] signatureData)
throws IOException {
PGPSignature signature = null;
String fingerprint = null;
String signer = null;
String keyId = null;
try (InputStream sigIn = new ByteArrayInputStream(signatureData)) {
signature = parseSignature(sigIn);
if (signature != null) {
// Try to figure out something to find the public key with.
if (signature.hasSubpackets()) {
PGPSignatureSubpacketVector packets = signature
.getHashedSubPackets();
IssuerFingerprint fingerprintPacket = packets
.getIssuerFingerprint();
if (fingerprintPacket != null) {
fingerprint = Hex
.toHexString(fingerprintPacket.getFingerprint())
.toLowerCase(Locale.ROOT);
}
signer = packets.getSignerUserID();
if (signer != null) {
signer = BouncyCastleGpgSigner.extractSignerId(signer);
}
}
keyId = Long.toUnsignedString(signature.getKeyID(), 16)
.toLowerCase(Locale.ROOT);
} else {
throw new JGitInternalException(BCText.get().nonSignatureError);
}
} catch (PGPException e) {
throw new JGitInternalException(BCText.get().signatureParseError,
e);
}
Date signatureCreatedAt = signature.getCreationTime();
if (fingerprint == null && signer == null && keyId == null) {
return new VerificationResult(signatureCreatedAt, null, null, null,
false, false, TrustLevel.UNKNOWN,
BCText.get().signatureNoKeyInfo);
}
if (fingerprint != null && keyId != null
&& !fingerprint.endsWith(keyId)) {
return new VerificationResult(signatureCreatedAt, signer, fingerprint,
null, false, false, TrustLevel.UNKNOWN,
MessageFormat.format(BCText.get().signatureInconsistent,
keyId, fingerprint));
}
if (fingerprint == null && keyId != null) {
fingerprint = keyId;
}
// Try to find the public key
String keySpec = '<' + signer + '>';
Object cached = null;
PGPPublicKey publicKey = null;
try {
cached = byFingerprint.get(fingerprint);
if (cached != null) {
if (cached instanceof PGPPublicKey) {
publicKey = (PGPPublicKey) cached;
}
} else if (!StringUtils.isEmptyOrNull(signer)) {
cached = bySigner.get(signer);
if (cached != null) {
if (cached instanceof PGPPublicKey) {
publicKey = (PGPPublicKey) cached;
}
}
}
if (cached == null) {
publicKey = BouncyCastleGpgKeyLocator.findPublicKey(fingerprint,
keySpec);
}
} catch (IOException | PGPException e) {
throw new JGitInternalException(
BCText.get().signatureKeyLookupError, e);
}
if (publicKey == null) {
if (cached == null) {
byFingerprint.put(fingerprint, NO_KEY);
byFingerprint.put(keyId, NO_KEY);
if (signer != null) {
bySigner.put(signer, NO_KEY);
}
}
return new VerificationResult(signatureCreatedAt, signer,
fingerprint, null, false, false, TrustLevel.UNKNOWN,
BCText.get().signatureNoPublicKey);
}
if (cached == null) {
byFingerprint.put(fingerprint, publicKey);
byFingerprint.put(keyId, publicKey);
if (signer != null) {
bySigner.put(signer, publicKey);
}
}
String user = null;
Iterator<String> userIds = publicKey.getUserIDs();
if (!StringUtils.isEmptyOrNull(signer)) {
while (userIds.hasNext()) {
String userId = userIds.next();
if (BouncyCastleGpgKeyLocator.containsSigningKey(userId,
keySpec)) {
user = userId;
break;
}
}
}
if (user == null) {
userIds = publicKey.getUserIDs();
if (userIds.hasNext()) {
user = userIds.next();
}
}
boolean expired = false;
long validFor = publicKey.getValidSeconds();
if (validFor > 0 && signatureCreatedAt != null) {
Instant expiredAt = publicKey.getCreationTime().toInstant()
.plusSeconds(validFor);
expired = expiredAt.isBefore(signatureCreatedAt.toInstant());
}
// Trust data is not defined in OpenPGP; the format is implementation
// specific. We don't use the GPG trustdb but simply the trust packet
// on the public key, if present. Even if present, it may or may not
// be set.
byte[] trustData = publicKey.getTrustData();
TrustLevel trust = parseGpgTrustPacket(trustData);
boolean verified = false;
try {
signature.init(
new JcaPGPContentVerifierBuilderProvider()
.setProvider(BouncyCastleProvider.PROVIDER_NAME),
publicKey);
signature.update(data);
verified = signature.verify();
} catch (PGPException e) {
throw new JGitInternalException(
BCText.get().signatureVerificationError, e);
}
return new VerificationResult(signatureCreatedAt, signer, fingerprint, user,
verified, expired, trust, null);
}