View Javadoc
1   /*
2    * Copyright 2024–2026 Michael Osipov
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package net.sf.michaelo.tomcat.pac;
17  
18  import java.util.Objects;
19  
20  /**
21   * A class representing the <a href=
22   * "https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/6e95edd3-af93-41d4-8303-6c7955297315">{@code PAC_SIGNATURE_DATA}</a>
23   * structure from MS-PAC.
24   */
25  public class PacSignatureData {
26  
27  	public enum SignatureType {
28  		HMAC_MD5(-138, 16, 23),
29  		HMAC_SHA1_96_AES128(15, 12, 17),
30  		HMAC_SHA1_96_AES256(16, 12, 18);
31  
32  		private final int value;
33  		private final int size;
34  		private final int eType;
35  
36  		SignatureType(int value, int size, int eType) {
37  			this.value = value;
38  			this.size = size;
39  			this.eType = eType;
40  		}
41  
42  		public int getValue() {
43  			return value;
44  		}
45  
46  		public int getSize() {
47  			return size;
48  		}
49  
50  		public int getEType() {
51  			return eType;
52  		}
53  	}
54  
55  	private final SignatureType type;
56  	private final byte[] signature;
57  
58  	/**
59  	 * Parses a PAC signature data object from a byte array.
60  	 *
61  	 * @param sigDataBytes PAC signature data structure encoded as bytes
62  	 * @throws NullPointerException if {@code sigDataBytes} is null
63  	 * @throws IllegalArgumentException if {@code sigDataBytes} is empty
64  	 * @throws IllegalArgumentException if encoded signature type is not supported by {@link SignatureType}
65  	 */
66  	public PacSignatureData(byte[] sigDataBytes) {
67  		Objects.requireNonNull(sigDataBytes, "sigDataBytes cannot be null");
68  		if (sigDataBytes.length == 0) throw new IllegalArgumentException("sigDataBytes cannot be empty");
69  
70  		PacDataBuffer buf = new PacDataBuffer(sigDataBytes);
71  
72  		// SignatureType
73  		int type = buf.getInt();
74  		if (type == SignatureType.HMAC_MD5.getValue()) {
75  			this.type = SignatureType.HMAC_MD5;
76  		} else if (type == SignatureType.HMAC_SHA1_96_AES128.getValue()) {
77  			this.type = SignatureType.HMAC_SHA1_96_AES128;
78  		} else if (type == SignatureType.HMAC_SHA1_96_AES256.getValue()) {
79  			this.type = SignatureType.HMAC_SHA1_96_AES256;
80  		} else {
81  			throw new IllegalArgumentException("Unsupported signature type " + type);
82  		}
83  
84  		// Signature
85  		this.signature = new byte[this.type.getSize()];
86  		buf.get(this.signature);
87  
88  		// RODCIdentifier ignored completely
89  	}
90  
91  	public SignatureType getType() {
92  		return type;
93  	}
94  
95  	public byte[] getSignature() {
96  		return signature;
97  	}
98  }