1 21 22 package org.apache.derby.impl.services.jce; 23 24 import org.apache.derby.iapi.services.crypto.CipherFactory; 25 import org.apache.derby.iapi.services.crypto.CipherProvider; 26 import org.apache.derby.iapi.services.sanity.SanityManager; 27 28 import org.apache.derby.iapi.error.StandardException; 29 import org.apache.derby.iapi.reference.SQLState; 30 31 import java.security.Key ; 32 import java.security.InvalidKeyException ; 33 import java.security.NoSuchAlgorithmException ; 34 import java.security.GeneralSecurityException ; 35 import java.security.NoSuchProviderException ; 36 37 import javax.crypto.Cipher; 38 import javax.crypto.spec.IvParameterSpec; 39 import javax.crypto.SecretKeyFactory; 40 import javax.crypto.spec.SecretKeySpec; 41 import javax.crypto.SecretKey; 42 43 44 49 class JCECipherProvider implements CipherProvider 50 { 51 private Cipher cipher; 52 private int mode; 53 private boolean ivUsed = true; 54 private final IvParameterSpec ivspec; 55 private final int encryptionBlockSize; 56 private boolean sunjce; 58 private SecretKey cryptixKey; 60 61 JCECipherProvider(int mode, SecretKey secretKey, byte[] iv, String algorithm, String provider) 62 throws StandardException 63 { 64 Throwable t; 65 ivspec = new IvParameterSpec(iv); 66 try 67 { 68 69 70 if (provider == null) 71 { 72 cipher = Cipher.getInstance(algorithm); 73 74 if ("SunJCE".equals(cipher.getProvider().getName())) 76 sunjce = true; 77 } 78 else 79 { 80 85 if( provider.equals("SunJCE") ) 86 { 87 sunjce = true; 88 } 89 else 90 { 91 97 if( provider.equals( "BouncyCastleProvider" ) ) 98 provider = "BC"; 99 } 100 101 cipher = Cipher.getInstance(algorithm,provider); 102 } 103 104 encryptionBlockSize = cipher.getBlockSize(); 107 108 this.mode = mode; 109 try { 110 111 if (mode == CipherFactory.ENCRYPT) 113 { 114 if ((algorithm.indexOf("/ECB") > -1)) 115 cipher.init(Cipher.ENCRYPT_MODE, secretKey); 116 else 117 cipher.init(Cipher.ENCRYPT_MODE, secretKey,ivspec); 118 } 119 else if (mode == CipherFactory.DECRYPT) 120 { 121 if ((algorithm.indexOf("/ECB") > -1)) 122 cipher.init(Cipher.DECRYPT_MODE, secretKey); 123 else 124 cipher.init(Cipher.DECRYPT_MODE, secretKey,ivspec); 125 } 126 else 127 throw StandardException.newException(SQLState.ILLEGAL_CIPHER_MODE); 128 } catch (InvalidKeyException ike) { 129 130 if (algorithm.startsWith("DES")) { 131 132 SecretKeyFactory skf; 133 if (provider == null) 134 skf = SecretKeyFactory.getInstance(secretKey.getAlgorithm()); 135 else 136 skf = SecretKeyFactory.getInstance(secretKey.getAlgorithm(), provider); 137 138 139 secretKey = skf.translateKey(new SecretKeySpec(secretKey.getEncoded(), secretKey.getAlgorithm())); 142 143 if (mode == CipherFactory.ENCRYPT ) 145 { 146 if ((algorithm.indexOf("/ECB") > -1)) 147 cipher.init(Cipher.ENCRYPT_MODE, secretKey); 148 else 149 cipher.init(Cipher.ENCRYPT_MODE, secretKey,ivspec); 150 } 151 else if (mode == CipherFactory.DECRYPT) 152 { 153 if ((algorithm.indexOf("/ECB") > -1)) 154 cipher.init(Cipher.DECRYPT_MODE, secretKey); 155 else 156 cipher.init(Cipher.DECRYPT_MODE, secretKey,ivspec); 157 } 158 159 } 160 else 161 throw StandardException.newException(SQLState.CRYPTO_EXCEPTION, ike); 162 } 163 cryptixKey = secretKey; 164 165 if (cipher.getIV() == null) 166 ivUsed = false; 167 168 if (SanityManager.DEBUG) 169 SanityManager.ASSERT(verifyIV(iv)); 170 171 return; 172 173 } 174 catch (InvalidKeyException ike) 175 { 176 t = ike; 177 } 178 catch (NoSuchAlgorithmException nsae) 179 { 180 throw StandardException.newException(SQLState.ENCRYPTION_NOSUCH_ALGORITHM, algorithm, JCECipherFactory.providerErrorName(provider)); 181 } 182 catch (NoSuchProviderException nspe) 183 { 184 throw StandardException.newException(SQLState.ENCRYPTION_BAD_PROVIDER, JCECipherFactory.providerErrorName(provider)); 185 } 186 catch (GeneralSecurityException gse) 187 { 188 t = gse; 189 } 190 throw StandardException.newException(SQLState.CRYPTO_EXCEPTION, t); 191 192 } 193 194 199 public int encrypt(byte[] cleartext, int offset, int length, 200 byte[] ciphertext, int outputOffset) 201 throws StandardException 202 { 203 if (SanityManager.DEBUG) 204 { 205 SanityManager.ASSERT(mode == CipherFactory.ENCRYPT, 206 "calling encrypt on a decryption engine"); 207 SanityManager.ASSERT(cleartext != null, "encrypting null cleartext"); 208 SanityManager.ASSERT(offset >= 0, "offset < 0"); 209 SanityManager.ASSERT(length > 0, "length <= 0"); 210 SanityManager.ASSERT(offset+length <= cleartext.length, 211 "offset+length > cleartext.length"); 212 SanityManager.ASSERT(length <= ciphertext.length-outputOffset, 213 "provided ciphertext buffer insufficient"); 214 } 215 216 int retval = 0; 217 try 218 { 219 synchronized(this) 222 { 223 if( !sunjce ) 224 { 225 try 227 { 228 if (mode == CipherFactory.ENCRYPT) 230 { 231 if (ivUsed) 232 cipher.init(Cipher.ENCRYPT_MODE, cryptixKey, ivspec); 233 else 234 cipher.init(Cipher.ENCRYPT_MODE,cryptixKey); 235 } 236 else if (mode == CipherFactory.DECRYPT) 237 { 238 if (ivUsed) 239 cipher.init(Cipher.DECRYPT_MODE, cryptixKey, ivspec); 240 else 241 cipher.init(Cipher.DECRYPT_MODE, cryptixKey); 242 } 243 244 } 245 catch (InvalidKeyException ike) 246 { 247 System.out.println("A " + ike); 248 throw StandardException.newException(SQLState.CRYPTO_EXCEPTION, ike); 249 } 250 } 251 252 retval = cipher.doFinal(cleartext, offset, length, ciphertext, outputOffset); 253 } 254 } 255 catch (IllegalStateException ise) 256 { 257 if (SanityManager.DEBUG) 259 SanityManager.THROWASSERT("Illegal state exception"); 260 } 261 catch (GeneralSecurityException gse) 262 { 263 System.out.println("B " + gse); 264 throw StandardException.newException(SQLState.CRYPTO_EXCEPTION, gse); 265 } 266 267 if (SanityManager.DEBUG) 268 SanityManager.ASSERT(retval == length, "ciphertext length != length"); 269 270 return retval; 271 } 272 273 274 279 public int decrypt(byte[] ciphertext, int offset, int length, 280 byte[] cleartext, int outputOffset) 281 throws StandardException 282 { 283 if (SanityManager.DEBUG) 284 { 285 SanityManager.ASSERT(mode == CipherFactory.DECRYPT, 286 "calling decrypt on a encryption engine"); 287 SanityManager.ASSERT(ciphertext != null, "decrypting null ciphertext"); 288 SanityManager.ASSERT(offset >= 0, "offset < 0"); 289 SanityManager.ASSERT(length > 0, "length <= 0"); 290 SanityManager.ASSERT(offset+length <= ciphertext.length, 291 "offset+length > ciphertext.length"); 292 SanityManager.ASSERT(length <= cleartext.length-outputOffset, 293 "provided cleartexte buffer insufficient"); 294 } 295 296 int retval = 0; 297 try 298 { 299 synchronized(this) 302 { 303 if( !sunjce ) 304 { 305 try 307 { 308 310 if (mode == CipherFactory.ENCRYPT) 311 { 312 if (ivUsed) 313 cipher.init(Cipher.ENCRYPT_MODE, cryptixKey, ivspec); 314 else 315 cipher.init(Cipher.ENCRYPT_MODE,cryptixKey); 316 } 317 else if (mode == CipherFactory.DECRYPT) 318 { 319 if (ivUsed) 320 cipher.init(Cipher.DECRYPT_MODE, cryptixKey, ivspec); 321 else 322 cipher.init(Cipher.DECRYPT_MODE, cryptixKey); 323 } 324 325 } 326 catch (InvalidKeyException ike) 327 { 328 System.out.println("C " + ike); 329 throw StandardException.newException(SQLState.CRYPTO_EXCEPTION, ike); 330 } 331 332 } 333 334 retval = cipher.doFinal(ciphertext, offset, length, cleartext, outputOffset); 335 } 336 } 337 catch (IllegalStateException ise) 338 { 339 if (SanityManager.DEBUG) 341 SanityManager.THROWASSERT("Illegal state exception"); 342 } 343 catch (GeneralSecurityException gse) 344 { 345 System.out.println("D " + gse); 346 throw StandardException.newException(SQLState.CRYPTO_EXCEPTION, gse); 347 } 348 349 if (SanityManager.DEBUG) 350 { 351 SanityManager.ASSERT(retval == length, 352 "cleartext length != length"); 353 } 354 355 return retval; 356 } 357 358 boolean verifyIV(byte[] IV) 359 { 360 byte[] myIV = cipher.getIV(); 361 if (myIV == null) 363 return !ivUsed; 364 if (myIV.length != IV.length) 365 return false; 366 for (int i = 0; i < IV.length; i++) 367 if (myIV[i] != IV[i]) 368 return false; 369 return true; 370 } 371 372 public int getEncryptionBlockSize() 373 { 374 return encryptionBlockSize; 375 } 376 } 377 | Popular Tags |