1/* 2 * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package sun.security.pkcs; 27 28import java.io.*; 29import sun.security.x509.*; 30import sun.security.util.DerValue; 31import sun.security.util.DerOutputStream; 32 33/** 34 * This class implements the <code>EncryptedPrivateKeyInfo</code> type, 35 * which is defined in PKCS #8 as follows: 36 * 37 * <pre> 38 * EncryptedPrivateKeyInfo ::= SEQUENCE { 39 * encryptionAlgorithm AlgorithmIdentifier, 40 * encryptedData OCTET STRING } 41 * </pre> 42 * 43 * @author Jan Luehe 44 * 45 */ 46 47public class EncryptedPrivateKeyInfo { 48 49 // the "encryptionAlgorithm" field 50 private AlgorithmId algid; 51 52 // the "encryptedData" field 53 private byte[] encryptedData; 54 55 // the ASN.1 encoded contents of this class 56 private byte[] encoded; 57 58 /** 59 * Constructs (i.e., parses) an <code>EncryptedPrivateKeyInfo</code> from 60 * its encoding. 61 */ 62 public EncryptedPrivateKeyInfo(byte[] encoded) 63 throws IOException 64 { 65 if (encoded == null) { 66 throw new IllegalArgumentException("encoding must not be null"); 67 } 68 69 DerValue val = new DerValue(encoded); 70 71 DerValue[] seq = new DerValue[2]; 72 73 seq[0] = val.data.getDerValue(); 74 seq[1] = val.data.getDerValue(); 75 76 if (val.data.available() != 0) { 77 throw new IOException("overrun, bytes = " + val.data.available()); 78 } 79 80 this.algid = AlgorithmId.parse(seq[0]); 81 if (seq[0].data.available() != 0) { 82 throw new IOException("encryptionAlgorithm field overrun"); 83 } 84 85 this.encryptedData = seq[1].getOctetString(); 86 if (seq[1].data.available() != 0) 87 throw new IOException("encryptedData field overrun"); 88 89 this.encoded = encoded.clone(); 90 } 91 92 /** 93 * Constructs an <code>EncryptedPrivateKeyInfo</code> from the 94 * encryption algorithm and the encrypted data. 95 */ 96 public EncryptedPrivateKeyInfo(AlgorithmId algid, byte[] encryptedData) { 97 this.algid = algid; 98 this.encryptedData = encryptedData.clone(); 99 } 100 101 /** 102 * Returns the encryption algorithm. 103 */ 104 public AlgorithmId getAlgorithm() { 105 return this.algid; 106 } 107 108 /** 109 * Returns the encrypted data. 110 */ 111 public byte[] getEncryptedData() { 112 return this.encryptedData.clone(); 113 } 114 115 /** 116 * Returns the ASN.1 encoding of this class. 117 */ 118 public byte[] getEncoded() 119 throws IOException 120 { 121 if (this.encoded != null) return this.encoded.clone(); 122 123 DerOutputStream out = new DerOutputStream(); 124 DerOutputStream tmp = new DerOutputStream(); 125 126 // encode encryption algorithm 127 algid.encode(tmp); 128 129 // encode encrypted data 130 tmp.putOctetString(encryptedData); 131 132 // wrap everything into a SEQUENCE 133 out.write(DerValue.tag_Sequence, tmp); 134 this.encoded = out.toByteArray(); 135 136 return this.encoded.clone(); 137 } 138 139 public boolean equals(Object other) { 140 if (this == other) 141 return true; 142 if (!(other instanceof EncryptedPrivateKeyInfo)) 143 return false; 144 try { 145 byte[] thisEncrInfo = this.getEncoded(); 146 byte[] otherEncrInfo 147 = ((EncryptedPrivateKeyInfo)other).getEncoded(); 148 149 if (thisEncrInfo.length != otherEncrInfo.length) 150 return false; 151 for (int i = 0; i < thisEncrInfo.length; i++) 152 if (thisEncrInfo[i] != otherEncrInfo[i]) 153 return false; 154 return true; 155 } catch (IOException e) { 156 return false; 157 } 158 } 159 160 /** 161 * Returns a hashcode for this EncryptedPrivateKeyInfo. 162 * 163 * @return a hashcode for this EncryptedPrivateKeyInfo. 164 */ 165 public int hashCode() { 166 int retval = 0; 167 168 for (int i = 0; i < this.encryptedData.length; i++) 169 retval += this.encryptedData[i] * i; 170 return retval; 171 } 172} 173