summaryrefslogtreecommitdiff
path: root/smcc/src/main/java/at/gv/egiz/smcc/Infobox.java
diff options
context:
space:
mode:
Diffstat (limited to 'smcc/src/main/java/at/gv/egiz/smcc/Infobox.java')
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/Infobox.java104
1 files changed, 104 insertions, 0 deletions
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/Infobox.java b/smcc/src/main/java/at/gv/egiz/smcc/Infobox.java
new file mode 100644
index 00000000..4eff6348
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/Infobox.java
@@ -0,0 +1,104 @@
+/*
+* Copyright 2009 Federal Chancellery Austria and
+* Graz University of Technology
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package at.gv.egiz.smcc;
+
+import java.security.AlgorithmParameters;
+import java.security.GeneralSecurityException;
+import java.util.Arrays;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESedeKeySpec;
+import javax.crypto.spec.IvParameterSpec;
+
+
+public class Infobox {
+
+ private int tag;
+
+ private byte[] data;
+
+ private byte[] encryptedKey;
+
+ public Infobox(int tag, int modifiers, byte[] data) throws InfoboxException {
+ this.tag = tag;
+ if ((modifiers & 0xFE) > 0) {
+ throw new InfoboxException("Infobox modifiers " + Integer.toBinaryString(modifiers) + " not supported.");
+ }
+ if ((modifiers & 0x01) > 0) {
+ int keyLenght = (0xFF & data[0]) + ((0xFF & data[1]) << 8);
+ this.encryptedKey = new byte[keyLenght];
+ System.arraycopy(data, 2, this.encryptedKey, 0, keyLenght);
+ int dataLength = data.length - 2 - keyLenght;
+ this.data = new byte[dataLength];
+ System.arraycopy(data, 2 + encryptedKey.length, this.data, 0, dataLength);
+ } else {
+ this.data = data;
+ }
+ }
+
+ public Infobox(byte[] data) {
+ this.data = data;
+ }
+
+ public int getTag() {
+ return tag;
+ }
+
+ public boolean isEncrypted() {
+ return encryptedKey != null;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+
+ public byte[] getEncryptedKey() {
+ return encryptedKey;
+ }
+
+ public byte[] decipher(byte[] plainKey) throws InfoboxException {
+
+ try {
+ Cipher cipher = Cipher
+ .getInstance("DESede/CBC/PKCS5Padding");
+ byte[] iv = new byte[8];
+ Arrays.fill(iv, (byte) 0x00);
+ IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
+ AlgorithmParameters parameters = AlgorithmParameters
+ .getInstance("DESede");
+ parameters.init(ivParameterSpec);
+
+ DESedeKeySpec keySpec = new DESedeKeySpec(plainKey);
+ SecretKeyFactory keyFactory = SecretKeyFactory
+ .getInstance("DESede");
+ SecretKey secretKey = keyFactory.generateSecret(keySpec);
+
+ cipher.init(Cipher.DECRYPT_MODE, secretKey, parameters);
+
+ return cipher.doFinal(data);
+
+ } catch (GeneralSecurityException e) {
+ throw new InfoboxException("Failed to decipher Infobox.", e);
+ }
+
+ }
+
+
+}