public SignatureVerification verify()

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);
	}