View Javadoc
1   /*
2    * Copyright 2024 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  
29  		HMAC_MD5(-138, 16, 23), HMAC_SHA1_96_AES128(15, 12, 17), HMAC_SHA1_96_AES256(16, 12, 18);
30  
31  		private final int value;
32  		private final int size;
33  		private final int eType;
34  
35  		SignatureType(int value, int size, int eType) {
36  			this.value = value;
37  			this.size = size;
38  			this.eType = eType;
39  		}
40  
41  		public int getValue() {
42  			return value;
43  		}
44  
45  		public int getSize() {
46  			return size;
47  		}
48  
49  		public int getEType() {
50  			return eType;
51  		}
52  	}
53  
54  	private final SignatureType type;
55  	private final byte[] signature;
56  
57  	/**
58  	 * Parses a PAC signature data object from a byte array.
59  	 *
60  	 * @param sigDataBytes
61  	 *            PAC signature data structure encoded as bytes
62  	 * @throws NullPointerException
63  	 *             if {@code sigDataBytes} is null
64  	 * @throws IllegalArgumentException
65  	 *             if {@code sigDataBytes} is empty
66  	 * @throws IllegalArgumentException
67  	 *             if encoded signature type is not supported by {@link SignatureType}
68  	 */
69  	public PacSignatureData(byte[] sigDataBytes) {
70  		Objects.requireNonNull(sigDataBytes, "sigDataBytes cannot be null");
71  		if (sigDataBytes.length == 0)
72  			throw new IllegalArgumentException("sigDataBytes cannot be empty");
73  
74  		PacDataBuffer buf = new PacDataBuffer(sigDataBytes);
75  
76  		// SignatureType
77  		int type = buf.getInt();
78  		if (type == SignatureType.HMAC_MD5.getValue()) {
79  			this.type = SignatureType.HMAC_MD5;
80  		} else if (type == SignatureType.HMAC_SHA1_96_AES128.getValue()) {
81  			this.type = SignatureType.HMAC_SHA1_96_AES128;
82  		} else if (type == SignatureType.HMAC_SHA1_96_AES256.getValue()) {
83  			this.type = SignatureType.HMAC_SHA1_96_AES256;
84  		} else {
85  			throw new IllegalArgumentException("Unsupported signature type " + type);
86  		}
87  
88  		// Signature
89  		this.signature = new byte[this.type.getSize()];
90  		buf.get(this.signature);
91  
92  		// RODCIdentifier ignored completely
93  	}
94  
95  	public SignatureType getType() {
96  		return type;
97  	}
98  
99  	public byte[] getSignature() {
100 		return signature;
101 	}
102 
103 }