1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.michaelo.tomcat.pac;
17
18 import java.security.Key;
19 import java.security.MessageDigest;
20 import java.security.SignatureException;
21 import java.util.ArrayList;
22 import java.util.Base64;
23 import java.util.List;
24 import java.util.stream.Collectors;
25
26 import net.sf.michaelo.tomcat.pac.PacSignatureData.SignatureType;
27
28 import sun.security.krb5.Checksum;
29 import sun.security.krb5.EncryptionKey;
30
31
32
33
34
35
36
37
38
39 public class PrivateSunPacSignatureVerifier extends PacSignatureVerifierBase {
40
41 @Override
42 protected void verifyInternal(PacSignatureData signatureData, byte[] data, Key[] keys) throws SignatureException {
43 SignatureType type = signatureData.getType();
44 byte[] expectedSignature = signatureData.getSignature();
45 List<byte[]> actualFailedSignatures = new ArrayList<>();
46 for (int i = 0; i < keys.length; i++) {
47 Key key = keys[i];
48 EncryptionKey encKey = new EncryptionKey(type.getEType(), key.getEncoded());
49 try {
50 Checksum checksum;
51 try {
52 checksum = new Checksum(type.getValue(), data, encKey, KU_KERB_NON_KERB_CKSUM_SALT);
53 } catch (Exception e) {
54 throw new SignatureException("Failed to calculate signature", e);
55 }
56
57 byte[] actualSignature = checksum.getBytes();
58 if (MessageDigest.isEqual(expectedSignature, actualSignature)) return;
59 else actualFailedSignatures.add(actualSignature);
60 } finally {
61 encKey.destroy();
62 }
63 }
64
65 String actualFailedSignaturesStr = actualFailedSignatures.stream()
66 .map(Base64.getEncoder()::encodeToString)
67 .collect(Collectors.joining(",", "[", "]"));
68 throw new SignatureException("Calculated signatures " + actualFailedSignaturesStr
69 + " do not match expected signature '"
70 + Base64.getEncoder().encodeToString(expectedSignature) + "'");
71 }
72 }