GNU Classpath (0.20) | |
Frames | No Frames |
1: /* EncryptedPrivateKeyInfo.java -- As in PKCS #8. 2: Copyright (C) 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.crypto; 40: 41: import gnu.java.security.OID; 42: import gnu.java.security.der.DER; 43: import gnu.java.security.der.DERReader; 44: import gnu.java.security.der.DERValue; 45: 46: import java.io.IOException; 47: import java.security.AlgorithmParameters; 48: import java.security.NoSuchAlgorithmException; 49: import java.security.spec.InvalidKeySpecException; 50: import java.security.spec.PKCS8EncodedKeySpec; 51: import java.util.ArrayList; 52: import java.util.List; 53: 54: /** 55: * An implementation of the <code>EncryptedPrivateKeyInfo</code> ASN.1 56: * type as specified in <a 57: * href="http://www.rsasecurity.com/rsalabs/pkcs/pkcs-8/">PKCS #8 - 58: * Private-Key Information Syntax Standard</a>. 59: * 60: * <p>The ASN.1 type <code>EncryptedPrivateKeyInfo</code> is: 61: * 62: * <blockquote> 63: * <pre>EncryptedPrivateKeyInfo ::= SEQUENCE { 64: * encryptionAlgorithm EncryptionAlgorithmIdentifier, 65: * encryptedData EncryptedData } 66: * 67: * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier 68: * 69: * EncrytpedData ::= OCTET STRING 70: * 71: * AlgorithmIdentifier ::= SEQUENCE { 72: * algorithm OBJECT IDENTIFIER, 73: * parameters ANY DEFINED BY algorithm OPTIONAL }</pre> 74: * </blockquote> 75: * 76: * @author Casey Marshall (csm@gnu.org) 77: * @since 1.4 78: * @see java.security.spec.PKCS8EncodedKeySpec 79: */ 80: public class EncryptedPrivateKeyInfo 81: { 82: 83: // Fields. 84: // ------------------------------------------------------------------------ 85: 86: /** The encrypted data. */ 87: private byte[] encryptedData; 88: 89: /** The encoded, encrypted key. */ 90: private byte[] encoded; 91: 92: /** The OID of the encryption algorithm. */ 93: private OID algOid; 94: 95: /** The encryption algorithm's parameters. */ 96: private AlgorithmParameters params; 97: 98: /** The encoded ASN.1 algorithm parameters. */ 99: private byte[] encodedParams; 100: 101: // Constructors. 102: // ------------------------------------------------------------------------ 103: 104: /** 105: * Create a new <code>EncryptedPrivateKeyInfo</code> object from raw 106: * encrypted data and the parameters used for encryption. 107: * 108: * <p>The <code>encryptedData</code> array is cloned. 109: * 110: * @param params The encryption algorithm parameters. 111: * @param encryptedData The encrypted key data. 112: * @throws java.lang.IllegalArgumentException If the 113: * <code>encryptedData</code> array is empty (zero-length). 114: * @throws java.security.NoSuchAlgorithmException If the algorithm 115: * specified in the parameters is not supported. 116: * @throws java.lang.NullPointerException If <code>encryptedData</code> 117: * is null. 118: */ 119: public EncryptedPrivateKeyInfo(AlgorithmParameters params, 120: byte[] encryptedData) 121: throws IllegalArgumentException, NoSuchAlgorithmException 122: { 123: if (encryptedData.length == 0) 124: { 125: throw new IllegalArgumentException("0-length encryptedData"); 126: } 127: this.params = params; 128: algOid = new OID(params.getAlgorithm()); 129: this.encryptedData = (byte[]) encryptedData.clone(); 130: } 131: 132: /** 133: * Create a new <code>EncryptedPrivateKeyInfo</code> from an encoded 134: * representation, parsing the ASN.1 sequence. 135: * 136: * @param encoded The encoded info. 137: * @throws java.io.IOException If parsing the encoded data fails. 138: * @throws java.lang.NullPointerException If <code>encoded</code> is 139: * null. 140: */ 141: public EncryptedPrivateKeyInfo(byte[] encoded) 142: throws IOException 143: { 144: this.encoded = (byte[]) encoded.clone(); 145: decode(); 146: } 147: 148: /** 149: * Create a new <code>EncryptedPrivateKeyInfo</code> from the cipher 150: * name and the encrytpedData. 151: * 152: * <p>The <code>encryptedData</code> array is cloned. 153: * 154: * @param algName The name of the algorithm (as an object identifier). 155: * @param encryptedData The encrypted key data. 156: * @throws java.lang.IllegalArgumentException If the 157: * <code>encryptedData</code> array is empty (zero-length). 158: * @throws java.security.NoSuchAlgorithmException If algName is not 159: * the name of a supported algorithm. 160: * @throws java.lang.NullPointerException If <code>encryptedData</code> 161: * is null. 162: */ 163: public EncryptedPrivateKeyInfo(String algName, byte[] encryptedData) 164: throws IllegalArgumentException, NoSuchAlgorithmException, 165: NullPointerException 166: { 167: if (encryptedData.length == 0) 168: { 169: throw new IllegalArgumentException("0-length encryptedData"); 170: } 171: this.algOid = new OID(algName); 172: this.encryptedData = (byte[]) encryptedData.clone(); 173: } 174: 175: // Instance methods. 176: // ------------------------------------------------------------------------ 177: 178: /** 179: * Return the name of the cipher used to encrypt this key. 180: * 181: * @return The algorithm name. 182: */ 183: public String getAlgName() 184: { 185: return algOid.toString(); 186: } 187: 188: public AlgorithmParameters getAlgParameters() 189: { 190: if (params == null && encodedParams != null) 191: { 192: try 193: { 194: params = AlgorithmParameters.getInstance(getAlgName()); 195: params.init(encodedParams); 196: } 197: catch (NoSuchAlgorithmException ignore) 198: { 199: } 200: catch (IOException ignore) 201: { 202: } 203: } 204: return params; 205: } 206: 207: public synchronized byte[] getEncoded() throws IOException 208: { 209: if (encoded == null) encode(); 210: return (byte[]) encoded.clone(); 211: } 212: 213: public byte[] getEncryptedData() 214: { 215: return encryptedData; 216: } 217: 218: public PKCS8EncodedKeySpec getKeySpec(Cipher cipher) 219: throws InvalidKeySpecException 220: { 221: try 222: { 223: return new PKCS8EncodedKeySpec(cipher.doFinal(encryptedData)); 224: } 225: catch (Exception x) 226: { 227: throw new InvalidKeySpecException(x.toString()); 228: } 229: } 230: 231: // Own methods. 232: // ------------------------------------------------------------------------- 233: 234: private void decode() throws IOException 235: { 236: DERReader der = new DERReader(encoded); 237: DERValue val = der.read(); 238: if (val.getTag() != DER.SEQUENCE) 239: throw new IOException("malformed EncryptedPrivateKeyInfo"); 240: val = der.read(); 241: if (val.getTag() != DER.SEQUENCE) 242: throw new IOException("malformed AlgorithmIdentifier"); 243: int algpLen = val.getLength(); 244: DERValue oid = der.read(); 245: if (oid.getTag() != DER.OBJECT_IDENTIFIER) 246: throw new IOException("malformed AlgorithmIdentifier"); 247: algOid = (OID) oid.getValue(); 248: if (algpLen == 0) 249: { 250: val = der.read(); 251: if (val.getTag() != 0) 252: { 253: encodedParams = val.getEncoded(); 254: der.read(); 255: } 256: } 257: else if (oid.getEncodedLength() < val.getLength()) 258: { 259: val = der.read(); 260: encodedParams = val.getEncoded(); 261: } 262: val = der.read(); 263: if (val.getTag() != DER.OCTET_STRING) 264: throw new IOException("malformed AlgorithmIdentifier"); 265: encryptedData = (byte[]) val.getValue(); 266: } 267: 268: private void encode() throws IOException 269: { 270: List algId = new ArrayList(2); 271: algId.add(new DERValue(DER.OBJECT_IDENTIFIER, algOid)); 272: getAlgParameters(); 273: if (params != null) 274: { 275: algId.add(DERReader.read(params.getEncoded())); 276: } 277: List epki = new ArrayList(2); 278: epki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, algId)); 279: epki.add(new DERValue(DER.OCTET_STRING, encryptedData)); 280: encoded = new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, epki).getEncoded(); 281: } 282: }
GNU Classpath (0.20) |