1 /* 2 * Copyright (c) 1998, 2018, 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 26 package com.sun.crypto.provider; 27 28 import java.io.*; 29 import java.math.BigInteger; 30 import java.security.AlgorithmParametersSpi; 31 import java.security.spec.AlgorithmParameterSpec; 32 import java.security.spec.InvalidParameterSpecException; 33 import javax.crypto.spec.PBEParameterSpec; 34 import sun.security.util.HexDumpEncoder; 35 import sun.security.util.*; 36 37 38 /** 39 * This class implements the parameter set used with password-based 40 * encryption, which is defined in PKCS#5 as follows: 41 * 42 * <pre> 43 * PBEParameter ::= SEQUENCE { 44 * salt OCTET STRING SIZE(8), 45 * iterationCount INTEGER } 46 * </pre> 47 * 48 * @author Jan Luehe 49 * 50 */ 51 52 public final class PBEParameters extends AlgorithmParametersSpi { 53 54 // the salt 55 private byte[] salt = null; 56 57 // the iteration count 58 private int iCount = 0; 59 60 // the cipher parameter 61 private AlgorithmParameterSpec cipherParam = null; 62 engineInit(AlgorithmParameterSpec paramSpec)63 protected void engineInit(AlgorithmParameterSpec paramSpec) 64 throws InvalidParameterSpecException 65 { 66 if (!(paramSpec instanceof PBEParameterSpec)) { 67 throw new InvalidParameterSpecException 68 ("Inappropriate parameter specification"); 69 } 70 this.salt = ((PBEParameterSpec)paramSpec).getSalt().clone(); 71 this.iCount = ((PBEParameterSpec)paramSpec).getIterationCount(); 72 this.cipherParam = ((PBEParameterSpec)paramSpec).getParameterSpec(); 73 } 74 engineInit(byte[] encoded)75 protected void engineInit(byte[] encoded) 76 throws IOException 77 { 78 try { 79 DerValue val = new DerValue(encoded); 80 if (val.tag != DerValue.tag_Sequence) { 81 throw new IOException("PBE parameter parsing error: " 82 + "not a sequence"); 83 } 84 val.data.reset(); 85 86 this.salt = val.data.getOctetString(); 87 this.iCount = val.data.getInteger(); 88 89 if (val.data.available() != 0) { 90 throw new IOException 91 ("PBE parameter parsing error: extra data"); 92 } 93 } catch (NumberFormatException e) { 94 throw new IOException("iteration count too big"); 95 } 96 } 97 engineInit(byte[] encoded, String decodingMethod)98 protected void engineInit(byte[] encoded, String decodingMethod) 99 throws IOException 100 { 101 engineInit(encoded); 102 } 103 104 protected <T extends AlgorithmParameterSpec> engineGetParameterSpec(Class<T> paramSpec)105 T engineGetParameterSpec(Class<T> paramSpec) 106 throws InvalidParameterSpecException 107 { 108 if (PBEParameterSpec.class.isAssignableFrom(paramSpec)) { 109 return paramSpec.cast( 110 new PBEParameterSpec(this.salt, this.iCount, this.cipherParam)); 111 } else { 112 throw new InvalidParameterSpecException 113 ("Inappropriate parameter specification"); 114 } 115 } 116 engineGetEncoded()117 protected byte[] engineGetEncoded() throws IOException { 118 DerOutputStream out = new DerOutputStream(); 119 DerOutputStream bytes = new DerOutputStream(); 120 121 bytes.putOctetString(this.salt); 122 bytes.putInteger(this.iCount); 123 124 out.write(DerValue.tag_Sequence, bytes); 125 return out.toByteArray(); 126 } 127 engineGetEncoded(String encodingMethod)128 protected byte[] engineGetEncoded(String encodingMethod) 129 throws IOException 130 { 131 return engineGetEncoded(); 132 } 133 134 /* 135 * Returns a formatted string describing the parameters. 136 */ engineToString()137 protected String engineToString() { 138 String LINE_SEP = System.lineSeparator(); 139 String saltString = LINE_SEP + " salt:" + LINE_SEP + "["; 140 HexDumpEncoder encoder = new HexDumpEncoder(); 141 saltString += encoder.encodeBuffer(salt); 142 saltString += "]"; 143 144 return saltString + LINE_SEP + " iterationCount:" 145 + LINE_SEP + Debug.toHexString(BigInteger.valueOf(iCount)) 146 + LINE_SEP; 147 } 148 } 149