1 // Copyright 2022 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 //////////////////////////////////////////////////////////////////////////////// 16 17 package com.google.crypto.tink.signature; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.junit.Assert.assertThrows; 21 22 import java.math.BigInteger; 23 import java.security.GeneralSecurityException; 24 import org.junit.Test; 25 import org.junit.runner.RunWith; 26 import org.junit.runners.JUnit4; 27 28 @RunWith(JUnit4.class) 29 public final class RsaSsaPkcs1ParametersTest { 30 31 @Test buildWithNoPrefixAndGetProperties()32 public void buildWithNoPrefixAndGetProperties() throws Exception { 33 RsaSsaPkcs1Parameters parameters = 34 RsaSsaPkcs1Parameters.builder() 35 .setModulusSizeBits(2048) 36 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 37 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 38 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 39 .build(); 40 assertThat(parameters.getModulusSizeBits()).isEqualTo(2048); 41 assertThat(parameters.getPublicExponent()).isEqualTo(RsaSsaPkcs1Parameters.F4); 42 assertThat(parameters.getHashType()).isEqualTo(RsaSsaPkcs1Parameters.HashType.SHA256); 43 assertThat(parameters.getVariant()).isEqualTo(RsaSsaPkcs1Parameters.Variant.NO_PREFIX); 44 assertThat(parameters.hasIdRequirement()).isFalse(); 45 } 46 47 @Test buildParametersWithoutSettingVariant_hasNoPrefix()48 public void buildParametersWithoutSettingVariant_hasNoPrefix() throws Exception { 49 RsaSsaPkcs1Parameters parameters = 50 RsaSsaPkcs1Parameters.builder() 51 .setModulusSizeBits(2048) 52 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 53 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 54 .build(); 55 assertThat(parameters.getVariant()).isEqualTo(RsaSsaPkcs1Parameters.Variant.NO_PREFIX); 56 assertThat(parameters.hasIdRequirement()).isFalse(); 57 } 58 59 @Test buildParametersWithoutExponent()60 public void buildParametersWithoutExponent() throws Exception { 61 RsaSsaPkcs1Parameters parameters = 62 RsaSsaPkcs1Parameters.builder() 63 .setModulusSizeBits(2048) 64 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 65 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 66 .build(); 67 assertThat(parameters.getPublicExponent()).isEqualTo(RsaSsaPkcs1Parameters.F4); 68 } 69 70 @Test buildParametersWithTinkPrefix()71 public void buildParametersWithTinkPrefix() throws Exception { 72 RsaSsaPkcs1Parameters parameters = 73 RsaSsaPkcs1Parameters.builder() 74 .setModulusSizeBits(2048) 75 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 76 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 77 .setVariant(RsaSsaPkcs1Parameters.Variant.TINK) 78 .build(); 79 assertThat(parameters.getVariant()).isEqualTo(RsaSsaPkcs1Parameters.Variant.TINK); 80 assertThat(parameters.hasIdRequirement()).isTrue(); 81 } 82 83 @Test buildParametersWithLegacyPrefix()84 public void buildParametersWithLegacyPrefix() throws Exception { 85 RsaSsaPkcs1Parameters parameters = 86 RsaSsaPkcs1Parameters.builder() 87 .setModulusSizeBits(2048) 88 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 89 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 90 .setVariant(RsaSsaPkcs1Parameters.Variant.LEGACY) 91 .build(); 92 assertThat(parameters.getVariant()).isEqualTo(RsaSsaPkcs1Parameters.Variant.LEGACY); 93 assertThat(parameters.hasIdRequirement()).isTrue(); 94 } 95 96 @Test buildParametersWithCrunchyPrefix()97 public void buildParametersWithCrunchyPrefix() throws Exception { 98 RsaSsaPkcs1Parameters parameters = 99 RsaSsaPkcs1Parameters.builder() 100 .setModulusSizeBits(2048) 101 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 102 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 103 .setVariant(RsaSsaPkcs1Parameters.Variant.CRUNCHY) 104 .build(); 105 assertThat(parameters.getVariant()).isEqualTo(RsaSsaPkcs1Parameters.Variant.CRUNCHY); 106 assertThat(parameters.hasIdRequirement()).isTrue(); 107 } 108 109 @Test buildParametersWithLargeModulusSize()110 public void buildParametersWithLargeModulusSize() throws Exception { 111 RsaSsaPkcs1Parameters parameters = 112 RsaSsaPkcs1Parameters.builder() 113 .setModulusSizeBits(16789) 114 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 115 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 116 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 117 .build(); 118 assertThat(parameters.getModulusSizeBits()).isEqualTo(16789); 119 } 120 121 @Test buildParametersWithValidNonF4PublicExponentSet()122 public void buildParametersWithValidNonF4PublicExponentSet() throws Exception { 123 RsaSsaPkcs1Parameters parameters = 124 RsaSsaPkcs1Parameters.builder() 125 .setModulusSizeBits(2048) 126 .setPublicExponent(BigInteger.valueOf(1234567)) 127 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 128 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 129 .build(); 130 assertThat(parameters.getPublicExponent()).isEqualTo(BigInteger.valueOf(1234567)); 131 } 132 133 @Test buildParametersWithSmallPublicExponent_fails()134 public void buildParametersWithSmallPublicExponent_fails() throws Exception { 135 assertThrows( 136 GeneralSecurityException.class, 137 () -> 138 RsaSsaPkcs1Parameters.builder() 139 .setModulusSizeBits(2048) 140 .setPublicExponent(BigInteger.valueOf(3)) 141 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 142 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 143 .build()); 144 } 145 146 @Test buildParametersWithEvenPublicExponent_fails()147 public void buildParametersWithEvenPublicExponent_fails() throws Exception { 148 assertThrows( 149 GeneralSecurityException.class, 150 () -> 151 RsaSsaPkcs1Parameters.builder() 152 .setModulusSizeBits(2048) 153 .setPublicExponent(BigInteger.valueOf(1234568)) 154 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 155 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 156 .build()); 157 } 158 159 @Test buildParametersWithLargePublicExponent_works()160 public void buildParametersWithLargePublicExponent_works() throws Exception { 161 BigInteger largeE = BigInteger.valueOf(100000000001L); 162 RsaSsaPkcs1Parameters parameters = 163 RsaSsaPkcs1Parameters.builder() 164 .setModulusSizeBits(2048) 165 .setPublicExponent(largeE) 166 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 167 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 168 .build(); 169 assertThat(parameters.getPublicExponent()).isEqualTo(largeE); 170 } 171 172 // Public exponents larger than 2^256 are rejected. See: 173 // https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf, B.3 174 @Test buildParametersWithTooLargePublicExponent_fails()175 public void buildParametersWithTooLargePublicExponent_fails() throws Exception { 176 BigInteger tooLargeE = BigInteger.valueOf(2).pow(256).add(BigInteger.ONE); 177 assertThat(tooLargeE.bitLength()).isEqualTo(257); 178 assertThrows( 179 GeneralSecurityException.class, 180 () -> 181 RsaSsaPkcs1Parameters.builder() 182 .setModulusSizeBits(2048) 183 .setPublicExponent(tooLargeE) 184 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 185 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 186 .build()); 187 } 188 189 @Test buildParametersWithSha384()190 public void buildParametersWithSha384() throws Exception { 191 RsaSsaPkcs1Parameters parameters = 192 RsaSsaPkcs1Parameters.builder() 193 .setModulusSizeBits(3072) 194 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 195 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA384) 196 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 197 .build(); 198 assertThat(parameters.getHashType()).isEqualTo(RsaSsaPkcs1Parameters.HashType.SHA384); 199 } 200 201 @Test buildParametersWithSha512()202 public void buildParametersWithSha512() throws Exception { 203 RsaSsaPkcs1Parameters parameters = 204 RsaSsaPkcs1Parameters.builder() 205 .setModulusSizeBits(4096) 206 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 207 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA512) 208 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 209 .build(); 210 assertThat(parameters.getHashType()).isEqualTo(RsaSsaPkcs1Parameters.HashType.SHA512); 211 } 212 213 @Test buildWithoutSettingModulusSize_fails()214 public void buildWithoutSettingModulusSize_fails() throws Exception { 215 assertThrows( 216 GeneralSecurityException.class, 217 () -> 218 RsaSsaPkcs1Parameters.builder() 219 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 220 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 221 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 222 .build()); 223 } 224 225 @Test buildWithoutSettingHashType_fails()226 public void buildWithoutSettingHashType_fails() throws Exception { 227 assertThrows( 228 GeneralSecurityException.class, 229 () -> 230 RsaSsaPkcs1Parameters.builder() 231 .setModulusSizeBits(2048) 232 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 233 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 234 .build()); 235 } 236 237 @Test buildWithVariantSetToNull_fails()238 public void buildWithVariantSetToNull_fails() throws Exception { 239 assertThrows( 240 GeneralSecurityException.class, 241 () -> 242 RsaSsaPkcs1Parameters.builder() 243 .setModulusSizeBits(2048) 244 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 245 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 246 .setVariant(null) 247 .build()); 248 } 249 250 @Test buildWithExponentSetToNull_fails()251 public void buildWithExponentSetToNull_fails() throws Exception { 252 assertThrows( 253 GeneralSecurityException.class, 254 () -> 255 RsaSsaPkcs1Parameters.builder() 256 .setModulusSizeBits(2048) 257 .setPublicExponent(null) 258 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 259 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 260 .build()); 261 } 262 263 @Test buildWithTooSmallModulusSize_fails()264 public void buildWithTooSmallModulusSize_fails() throws Exception { 265 assertThrows( 266 GeneralSecurityException.class, 267 () -> 268 RsaSsaPkcs1Parameters.builder() 269 .setModulusSizeBits(2047) 270 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 271 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 272 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 273 .build()); 274 } 275 276 @Test testEqualsAndEqualHashCode()277 public void testEqualsAndEqualHashCode() throws Exception { 278 RsaSsaPkcs1Parameters parameters1 = 279 RsaSsaPkcs1Parameters.builder() 280 .setModulusSizeBits(2048) 281 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 282 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 283 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 284 .build(); 285 RsaSsaPkcs1Parameters parameters2 = 286 RsaSsaPkcs1Parameters.builder() 287 .setModulusSizeBits(2048) 288 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 289 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 290 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 291 .build(); 292 293 assertThat(parameters1).isEqualTo(parameters2); 294 assertThat(parameters1.hashCode()).isEqualTo(parameters2.hashCode()); 295 } 296 297 @Test testNotEqual()298 public void testNotEqual() throws Exception { 299 RsaSsaPkcs1Parameters parameters = 300 RsaSsaPkcs1Parameters.builder() 301 .setModulusSizeBits(2048) 302 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 303 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 304 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 305 .build(); 306 assertThat(parameters) 307 .isNotEqualTo( 308 RsaSsaPkcs1Parameters.builder() 309 .setModulusSizeBits(2049) 310 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 311 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 312 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 313 .build()); 314 assertThat(parameters) 315 .isNotEqualTo( 316 RsaSsaPkcs1Parameters.builder() 317 .setModulusSizeBits(2048) 318 .setPublicExponent(BigInteger.valueOf(65539)) 319 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA256) 320 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 321 .build()); 322 assertThat(parameters) 323 .isNotEqualTo( 324 RsaSsaPkcs1Parameters.builder() 325 .setModulusSizeBits(2048) 326 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 327 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA384) 328 .setVariant(RsaSsaPkcs1Parameters.Variant.NO_PREFIX) 329 .build()); 330 assertThat(parameters) 331 .isNotEqualTo( 332 RsaSsaPkcs1Parameters.builder() 333 .setModulusSizeBits(2048) 334 .setPublicExponent(RsaSsaPkcs1Parameters.F4) 335 .setHashType(RsaSsaPkcs1Parameters.HashType.SHA384) 336 .setVariant(RsaSsaPkcs1Parameters.Variant.TINK) 337 .build()); 338 } 339 } 340