1/* 2 * Copyright (C) 2009 The Android Open Source Project 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 */ 16package libcore.javax.crypto.spec; 17 18import java.security.AlgorithmParameters; 19import java.security.NoSuchAlgorithmException; 20import java.security.Provider; 21import java.security.Security; 22import java.security.spec.MGF1ParameterSpec; 23import java.util.Arrays; 24import java.util.Base64; 25import javax.crypto.spec.OAEPParameterSpec; 26import javax.crypto.spec.PSource; 27import tests.security.AlgorithmParameterAsymmetricHelper; 28import tests.security.AlgorithmParametersTest; 29 30public class AlgorithmParametersTestOAEP extends AlgorithmParametersTest { 31 32 // The ASN.1 encoding for OAEP params (specified in RFC 4055 section 4.1) specifies 33 // default values for all parameters, so we need to consider encodings with those 34 // values both explicitly specified and unspecified. When encoding values, it is required 35 // that default values are left empty, but implementations must be able to parse explicitly- 36 // specified defaults as well. 37 // 38 // See README.ASN1 for how to understand and reproduce this data. 39 40 // asn1=SEQUENCE 41 private static final String ENCODED_DATA_ALL_DEFAULTS = "MAA="; 42 43 // asn1=SEQUENCE:oaep 44 // [oaep] 45 // hashFunc=EXP:0,SEQUENCE:sha1 46 // maskGenFunc=EXP:1,SEQUENCE:mgf1 47 // pSourceFunc=EXP:2,SEQUENCE:pSpecified 48 // [mgf1] 49 // oid=OID:1.2.840.113549.1.1.8 50 // params=SEQUENCE:sha1 51 // [pSpecified] 52 // oid=OID:1.2.840.113549.1.1.9 53 // val=OCTETSTRING: 54 // [sha1] 55 // oid=OID:sha1 56 // params=NULL 57 private static final String ENCODED_DATA_EXPLICIT_DEFAULTS = 58 "MDigCzAJBgUrDgMCGgUAoRgwFgYJKoZIhvcNAQEIMAkGBSsOAwIaBQCiDzANBgkqhkiG9w0BAQkEAA=="; 59 60 // Base64 version of ASN.1-encoded data with none of the default values. Specifically: 61 // SHA-256 hashFunc, MGF1-SHA-384 maskGenFunc, and [1, 2, 3, 4] pSourceFunc 62 63 // asn1=SEQUENCE:oaep 64 // [oaep] 65 // hashFunc=EXP:0,SEQUENCE:sha256 66 // maskGenFunc=EXP:1,SEQUENCE:mgf1 67 // pSourceFunc=EXP:2,SEQUENCE:pSpecified 68 // [sha256] 69 // oid=OID:sha256 70 // params=NULL 71 // [mgf1] 72 // oid=OID:1.2.840.113549.1.1.8 73 // params=SEQUENCE:sha384 74 // [sha384] 75 // oid=OID:sha384 76 // params=NULL 77 // [pSpecified] 78 // oid=OID:1.2.840.113549.1.1.9 79 // val=FORMAT:HEX,OCTETSTRING:01020304 80 private static final String ENCODED_DATA_NON_DEFAULTS = "MESgDzANBglghkgBZQMEAgEFAKEc" 81 + "MBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgIFAKITMBEGCSqGSIb3DQEBCQQEAQIDBA=="; 82 83 // Base64 version of ASN.1-encoded data with some default and some non-default values. 84 // Specifically, SHA-1 hashFunc (default), MGF1-SHA-512 maskGenFunc (non-default), 85 // empty pSourceFunc (default) 86 87 // asn1=SEQUENCE:oaep 88 // [oaep] 89 // maskGenFunc=EXP:1,SEQUENCE:mgf1 90 // [mgf1] 91 // oid=OID:1.2.840.113549.1.1.8 92 // params=SEQUENCE:sha512 93 // [sha512] 94 // oid=OID:sha512 95 // params=NULL 96 private static final String ENCODED_DATA_MIXED = "MB6hHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIDBQA="; 97 98 public AlgorithmParametersTestOAEP() { 99 super("OAEP", new AlgorithmParameterAsymmetricHelper("RSA"), new OAEPParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); 100 } 101 102 public void testEncoding() throws Exception { 103 for (Provider p : Security.getProviders()) { 104 AlgorithmParameters params; 105 try { 106 params = AlgorithmParameters.getInstance("OAEP", p); 107 } catch (NoSuchAlgorithmException e) { 108 // This provider doesn't support OAEP, ignore 109 continue; 110 } 111 112 OAEPParameterSpec spec = new OAEPParameterSpec( 113 "SHA-1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT); 114 params.init(spec); 115 assertEquals("Provider: " + p.getName(), 116 ENCODED_DATA_ALL_DEFAULTS, 117 Base64.getEncoder().encodeToString(params.getEncoded())); 118 119 params = AlgorithmParameters.getInstance("OAEP", p); 120 spec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA384, 121 new PSource.PSpecified(new byte[] {1, 2, 3, 4})); 122 params.init(spec); 123 assertEquals("Provider: " + p.getName(), 124 ENCODED_DATA_NON_DEFAULTS, 125 Base64.getEncoder().encodeToString(params.getEncoded())); 126 127 params = AlgorithmParameters.getInstance("OAEP", p); 128 spec = new OAEPParameterSpec( 129 "SHA-1", "MGF1", MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT); 130 params.init(spec); 131 assertEquals("Provider: " + p.getName(), 132 ENCODED_DATA_MIXED, 133 Base64.getEncoder().encodeToString(params.getEncoded())); 134 135 params = AlgorithmParameters.getInstance("OAEP", p); 136 params.init(Base64.getDecoder().decode(ENCODED_DATA_ALL_DEFAULTS)); 137 OAEPParameterSpec producedSpec = params.getParameterSpec(OAEPParameterSpec.class); 138 139 assertEquals("Provider: " + p.getName(), "SHA-1", producedSpec.getDigestAlgorithm()); 140 assertEquals("Provider: " + p.getName(), "MGF1", producedSpec.getMGFAlgorithm()); 141 assertEquals("Provider: " + p.getName(), 142 MGF1ParameterSpec.SHA1.getDigestAlgorithm(), 143 ((MGF1ParameterSpec) producedSpec.getMGFParameters()).getDigestAlgorithm()); 144 assertTrue("Provider: " + p.getName(), 145 Arrays.equals(PSource.PSpecified.DEFAULT.getValue(), 146 ((PSource.PSpecified) producedSpec.getPSource()).getValue())); 147 148 params = AlgorithmParameters.getInstance("OAEP", p); 149 params.init(Base64.getDecoder().decode(ENCODED_DATA_EXPLICIT_DEFAULTS)); 150 producedSpec = params.getParameterSpec(OAEPParameterSpec.class); 151 152 assertEquals("Provider: " + p.getName(), "SHA-1", producedSpec.getDigestAlgorithm()); 153 assertEquals("Provider: " + p.getName(), "MGF1", producedSpec.getMGFAlgorithm()); 154 assertEquals("Provider: " + p.getName(), 155 MGF1ParameterSpec.SHA1.getDigestAlgorithm(), 156 ((MGF1ParameterSpec) producedSpec.getMGFParameters()).getDigestAlgorithm()); 157 assertTrue("Provider: " + p.getName(), 158 Arrays.equals(PSource.PSpecified.DEFAULT.getValue(), 159 ((PSource.PSpecified) producedSpec.getPSource()).getValue())); 160 161 params = AlgorithmParameters.getInstance("OAEP", p); 162 params.init(Base64.getDecoder().decode(ENCODED_DATA_NON_DEFAULTS)); 163 producedSpec = params.getParameterSpec(OAEPParameterSpec.class); 164 165 assertEquals("Provider: " + p.getName(), "SHA-256", producedSpec.getDigestAlgorithm()); 166 assertEquals("Provider: " + p.getName(), "MGF1", producedSpec.getMGFAlgorithm()); 167 assertEquals("Provider: " + p.getName(), 168 MGF1ParameterSpec.SHA384.getDigestAlgorithm(), 169 ((MGF1ParameterSpec) producedSpec.getMGFParameters()).getDigestAlgorithm()); 170 assertTrue("Provider: " + p.getName(), 171 Arrays.equals(new byte[] {1, 2, 3, 4}, 172 ((PSource.PSpecified) producedSpec.getPSource()).getValue())); 173 174 params = AlgorithmParameters.getInstance("OAEP", p); 175 params.init(Base64.getDecoder().decode(ENCODED_DATA_MIXED)); 176 producedSpec = params.getParameterSpec(OAEPParameterSpec.class); 177 178 assertEquals("Provider: " + p.getName(), "SHA-1", producedSpec.getDigestAlgorithm()); 179 assertEquals("Provider: " + p.getName(), "MGF1", producedSpec.getMGFAlgorithm()); 180 assertEquals("Provider: " + p.getName(), 181 MGF1ParameterSpec.SHA512.getDigestAlgorithm(), 182 ((MGF1ParameterSpec) producedSpec.getMGFParameters()).getDigestAlgorithm()); 183 assertTrue("Provider: " + p.getName(), 184 Arrays.equals(PSource.PSpecified.DEFAULT.getValue(), 185 ((PSource.PSpecified) producedSpec.getPSource()).getValue())); 186 } 187 } 188 189} 190