| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/android/keystore_openssl.h" | 5 #include "net/android/keystore_openssl.h" |
| 6 | 6 |
| 7 #include <jni.h> | 7 #include <jni.h> |
| 8 #include <openssl/bn.h> | 8 #include <openssl/bn.h> |
| 9 // This include is required to get the ECDSA_METHOD structure definition | 9 // This include is required to get the ECDSA_METHOD structure definition |
| 10 // which isn't currently part of the OpenSSL official ABI. This should | 10 // which isn't currently part of the OpenSSL official ABI. This should |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 int padding) { | 129 int padding) { |
| 130 NOTIMPLEMENTED(); | 130 NOTIMPLEMENTED(); |
| 131 RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); | 131 RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); |
| 132 return -1; | 132 return -1; |
| 133 } | 133 } |
| 134 | 134 |
| 135 // See RSA_eay_private_encrypt in | 135 // See RSA_eay_private_encrypt in |
| 136 // third_party/openssl/openssl/crypto/rsa/rsa_eay.c for the default | 136 // third_party/openssl/openssl/crypto/rsa/rsa_eay.c for the default |
| 137 // implementation of this function. | 137 // implementation of this function. |
| 138 int RsaMethodPrivEnc(int flen, | 138 int RsaMethodPrivEnc(int flen, |
| 139 const unsigned char *from, | 139 const unsigned char* from, |
| 140 unsigned char *to, | 140 unsigned char* to, |
| 141 RSA *rsa, | 141 RSA* rsa, |
| 142 int padding) { | 142 int padding) { |
| 143 DCHECK_EQ(RSA_PKCS1_PADDING, padding); | 143 DCHECK_EQ(RSA_PKCS1_PADDING, padding); |
| 144 if (padding != RSA_PKCS1_PADDING) { | 144 if (padding != RSA_PKCS1_PADDING) { |
| 145 // TODO(davidben): If we need to, we can implement RSA_NO_PADDING | 145 // TODO(davidben): If we need to, we can implement RSA_NO_PADDING |
| 146 // by using javax.crypto.Cipher and picking either the | 146 // by using javax.crypto.Cipher and picking either the |
| 147 // "RSA/ECB/NoPadding" or "RSA/ECB/PKCS1Padding" transformation as | 147 // "RSA/ECB/NoPadding" or "RSA/ECB/PKCS1Padding" transformation as |
| 148 // appropriate. I believe support for both of these was added in | 148 // appropriate. I believe support for both of these was added in |
| 149 // the same Android version as the "NONEwithRSA" | 149 // the same Android version as the "NONEwithRSA" |
| 150 // java.security.Signature algorithm, so the same version checks | 150 // java.security.Signature algorithm, so the same version checks |
| 151 // for GetRsaLegacyKey should work. | 151 // for GetRsaLegacyKey should work. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 166 // For RSA keys, this function behaves as RSA_private_encrypt with | 166 // For RSA keys, this function behaves as RSA_private_encrypt with |
| 167 // PKCS#1 padding. | 167 // PKCS#1 padding. |
| 168 if (!RawSignDigestWithPrivateKey(private_key, from_piece, &result)) { | 168 if (!RawSignDigestWithPrivateKey(private_key, from_piece, &result)) { |
| 169 LOG(WARNING) << "Could not sign message in RsaMethodPrivEnc!"; | 169 LOG(WARNING) << "Could not sign message in RsaMethodPrivEnc!"; |
| 170 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); | 170 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); |
| 171 return -1; | 171 return -1; |
| 172 } | 172 } |
| 173 | 173 |
| 174 size_t expected_size = static_cast<size_t>(RSA_size(rsa)); | 174 size_t expected_size = static_cast<size_t>(RSA_size(rsa)); |
| 175 if (result.size() > expected_size) { | 175 if (result.size() > expected_size) { |
| 176 LOG(ERROR) << "RSA Signature size mismatch, actual: " | 176 LOG(ERROR) << "RSA Signature size mismatch, actual: " << result.size() |
| 177 << result.size() << ", expected <= " << expected_size; | 177 << ", expected <= " << expected_size; |
| 178 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); | 178 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); |
| 179 return -1; | 179 return -1; |
| 180 } | 180 } |
| 181 | 181 |
| 182 // Copy result to OpenSSL-provided buffer. RawSignDigestWithPrivateKey | 182 // Copy result to OpenSSL-provided buffer. RawSignDigestWithPrivateKey |
| 183 // should pad with leading 0s, but if it doesn't, pad the result. | 183 // should pad with leading 0s, but if it doesn't, pad the result. |
| 184 size_t zero_pad = expected_size - result.size(); | 184 size_t zero_pad = expected_size - result.size(); |
| 185 memset(to, 0, zero_pad); | 185 memset(to, 0, zero_pad); |
| 186 memcpy(to + zero_pad, &result[0], result.size()); | 186 memcpy(to + zero_pad, &result[0], result.size()); |
| 187 | 187 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 209 if (key != NULL) { | 209 if (key != NULL) { |
| 210 RSA_set_app_data(rsa, NULL); | 210 RSA_set_app_data(rsa, NULL); |
| 211 ReleaseKey(key); | 211 ReleaseKey(key); |
| 212 } | 212 } |
| 213 // Actual return value is ignored by OpenSSL. There are no docs | 213 // Actual return value is ignored by OpenSSL. There are no docs |
| 214 // explaining what this is supposed to be. | 214 // explaining what this is supposed to be. |
| 215 return 0; | 215 return 0; |
| 216 } | 216 } |
| 217 | 217 |
| 218 const RSA_METHOD android_rsa_method = { | 218 const RSA_METHOD android_rsa_method = { |
| 219 /* .name = */ "Android signing-only RSA method", | 219 /* .name = */ "Android signing-only RSA method", |
| 220 /* .rsa_pub_enc = */ RsaMethodPubEnc, | 220 /* .rsa_pub_enc = */ RsaMethodPubEnc, |
| 221 /* .rsa_pub_dec = */ RsaMethodPubDec, | 221 /* .rsa_pub_dec = */ RsaMethodPubDec, |
| 222 /* .rsa_priv_enc = */ RsaMethodPrivEnc, | 222 /* .rsa_priv_enc = */ RsaMethodPrivEnc, |
| 223 /* .rsa_priv_dec = */ RsaMethodPrivDec, | 223 /* .rsa_priv_dec = */ RsaMethodPrivDec, |
| 224 /* .rsa_mod_exp = */ NULL, | 224 /* .rsa_mod_exp = */ NULL, |
| 225 /* .bn_mod_exp = */ NULL, | 225 /* .bn_mod_exp = */ NULL, |
| 226 /* .init = */ RsaMethodInit, | 226 /* .init = */ RsaMethodInit, |
| 227 /* .finish = */ RsaMethodFinish, | 227 /* .finish = */ RsaMethodFinish, |
| 228 // This flag is necessary to tell OpenSSL to avoid checking the content | 228 // This flag is necessary to tell OpenSSL to avoid checking the content |
| 229 // (i.e. internal fields) of the private key. Otherwise, it will complain | 229 // (i.e. internal fields) of the private key. Otherwise, it will complain |
| 230 // it's not valid for the certificate. | 230 // it's not valid for the certificate. |
| 231 /* .flags = */ RSA_METHOD_FLAG_NO_CHECK, | 231 /* .flags = */ RSA_METHOD_FLAG_NO_CHECK, |
| 232 /* .app_data = */ NULL, | 232 /* .app_data = */ NULL, |
| 233 /* .rsa_sign = */ NULL, | 233 /* .rsa_sign = */ NULL, |
| 234 /* .rsa_verify = */ NULL, | 234 /* .rsa_verify = */ NULL, |
| 235 /* .rsa_keygen = */ NULL, | 235 /* .rsa_keygen = */ NULL, |
| 236 }; | 236 }; |
| 237 | 237 |
| 238 // Copy the contents of an encoded big integer into an existing BIGNUM. | 238 // Copy the contents of an encoded big integer into an existing BIGNUM. |
| 239 // This function modifies |*num| in-place. | 239 // This function modifies |*num| in-place. |
| 240 // |new_bytes| is the byte encoding of the new value. | 240 // |new_bytes| is the byte encoding of the new value. |
| 241 // |num| points to the BIGNUM which will be assigned with the new value. | 241 // |num| points to the BIGNUM which will be assigned with the new value. |
| 242 // Returns true on success, false otherwise. On failure, |*num| is | 242 // Returns true on success, false otherwise. On failure, |*num| is |
| 243 // not modified. | 243 // not modified. |
| 244 bool CopyBigNumFromBytes(const std::vector<uint8>& new_bytes, | 244 bool CopyBigNumFromBytes(const std::vector<uint8>& new_bytes, BIGNUM* num) { |
| 245 BIGNUM* num) { | 245 BIGNUM* ret = BN_bin2bn(reinterpret_cast<const unsigned char*>(&new_bytes[0]), |
| 246 BIGNUM* ret = BN_bin2bn( | 246 static_cast<int>(new_bytes.size()), |
| 247 reinterpret_cast<const unsigned char*>(&new_bytes[0]), | 247 num); |
| 248 static_cast<int>(new_bytes.size()), | |
| 249 num); | |
| 250 return (ret != NULL); | 248 return (ret != NULL); |
| 251 } | 249 } |
| 252 | 250 |
| 253 // Decode the contents of an encoded big integer and either create a new | 251 // Decode the contents of an encoded big integer and either create a new |
| 254 // BIGNUM object (if |*num_ptr| is NULL on input) or copy it (if | 252 // BIGNUM object (if |*num_ptr| is NULL on input) or copy it (if |
| 255 // |*num_ptr| is not NULL). | 253 // |*num_ptr| is not NULL). |
| 256 // |new_bytes| is the byte encoding of the new value. | 254 // |new_bytes| is the byte encoding of the new value. |
| 257 // |num_ptr| is the address of a BIGNUM pointer. |*num_ptr| can be NULL. | 255 // |num_ptr| is the address of a BIGNUM pointer. |*num_ptr| can be NULL. |
| 258 // Returns true on success, false otherwise. On failure, |*num_ptr| is | 256 // Returns true on success, false otherwise. On failure, |*num_ptr| is |
| 259 // not modified. On success, |*num_ptr| will always be non-NULL and | 257 // not modified. On success, |*num_ptr| will always be non-NULL and |
| 260 // point to a valid BIGNUM object. | 258 // point to a valid BIGNUM object. |
| 261 bool SwapBigNumPtrFromBytes(const std::vector<uint8>& new_bytes, | 259 bool SwapBigNumPtrFromBytes(const std::vector<uint8>& new_bytes, |
| 262 BIGNUM** num_ptr) { | 260 BIGNUM** num_ptr) { |
| 263 BIGNUM* old_num = *num_ptr; | 261 BIGNUM* old_num = *num_ptr; |
| 264 BIGNUM* new_num = BN_bin2bn( | 262 BIGNUM* new_num = |
| 265 reinterpret_cast<const unsigned char*>(&new_bytes[0]), | 263 BN_bin2bn(reinterpret_cast<const unsigned char*>(&new_bytes[0]), |
| 266 static_cast<int>(new_bytes.size()), | 264 static_cast<int>(new_bytes.size()), |
| 267 old_num); | 265 old_num); |
| 268 if (new_num == NULL) | 266 if (new_num == NULL) |
| 269 return false; | 267 return false; |
| 270 | 268 |
| 271 if (old_num == NULL) | 269 if (old_num == NULL) |
| 272 *num_ptr = new_num; | 270 *num_ptr = new_num; |
| 273 return true; | 271 return true; |
| 274 } | 272 } |
| 275 | 273 |
| 276 // Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object. | 274 // Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object. |
| 277 // |private_key| is the JNI reference (local or global) to the object. | 275 // |private_key| is the JNI reference (local or global) to the object. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 EVP_PKEY_assign_RSA(pkey, rsa.release()); | 307 EVP_PKEY_assign_RSA(pkey, rsa.release()); |
| 310 return true; | 308 return true; |
| 311 } | 309 } |
| 312 | 310 |
| 313 // Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object | 311 // Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object |
| 314 // for Android 4.0 to 4.1.x. Must only be used on Android < 4.2. | 312 // for Android 4.0 to 4.1.x. Must only be used on Android < 4.2. |
| 315 // |private_key| is a JNI reference (local or global) to the object. | 313 // |private_key| is a JNI reference (local or global) to the object. |
| 316 // |pkey| is the EVP_PKEY to setup as a wrapper. | 314 // |pkey| is the EVP_PKEY to setup as a wrapper. |
| 317 // Returns true on success, false otherwise. | 315 // Returns true on success, false otherwise. |
| 318 EVP_PKEY* GetRsaLegacyKey(jobject private_key) { | 316 EVP_PKEY* GetRsaLegacyKey(jobject private_key) { |
| 319 EVP_PKEY* sys_pkey = | 317 EVP_PKEY* sys_pkey = GetOpenSSLSystemHandleForPrivateKey(private_key); |
| 320 GetOpenSSLSystemHandleForPrivateKey(private_key); | |
| 321 if (sys_pkey != NULL) { | 318 if (sys_pkey != NULL) { |
| 322 CRYPTO_add(&sys_pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); | 319 CRYPTO_add(&sys_pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); |
| 323 } else { | 320 } else { |
| 324 // GetOpenSSLSystemHandleForPrivateKey() will fail on Android | 321 // GetOpenSSLSystemHandleForPrivateKey() will fail on Android |
| 325 // 4.0.3 and earlier. However, it is possible to get the key | 322 // 4.0.3 and earlier. However, it is possible to get the key |
| 326 // content with PrivateKey.getEncoded() on these platforms. | 323 // content with PrivateKey.getEncoded() on these platforms. |
| 327 // Note that this method may return NULL on 4.0.4 and later. | 324 // Note that this method may return NULL on 4.0.4 and later. |
| 328 std::vector<uint8> encoded; | 325 std::vector<uint8> encoded; |
| 329 if (!GetPrivateKeyEncodedBytes(private_key, &encoded)) { | 326 if (!GetPrivateKeyEncodedBytes(private_key, &encoded)) { |
| 330 LOG(ERROR) << "Can't get private key data!"; | 327 LOG(ERROR) << "Can't get private key data!"; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 345 // Custom DSA_METHOD that uses the platform APIs. | 342 // Custom DSA_METHOD that uses the platform APIs. |
| 346 // Note that for now, only signing through DSA_sign() is really supported. | 343 // Note that for now, only signing through DSA_sign() is really supported. |
| 347 // all other method pointers are either stubs returning errors, or no-ops. | 344 // all other method pointers are either stubs returning errors, or no-ops. |
| 348 // See <openssl/dsa.h> for exact declaration of DSA_METHOD. | 345 // See <openssl/dsa.h> for exact declaration of DSA_METHOD. |
| 349 // | 346 // |
| 350 // Note: There is no DSA_set_app_data() and DSA_get_app_data() functions, | 347 // Note: There is no DSA_set_app_data() and DSA_get_app_data() functions, |
| 351 // but RSA_set_app_data() is defined as a simple macro that calls | 348 // but RSA_set_app_data() is defined as a simple macro that calls |
| 352 // RSA_set_ex_data() with a hard-coded index of 0, so this code | 349 // RSA_set_ex_data() with a hard-coded index of 0, so this code |
| 353 // does the same thing here. | 350 // does the same thing here. |
| 354 | 351 |
| 355 DSA_SIG* DsaMethodDoSign(const unsigned char* dgst, | 352 DSA_SIG* DsaMethodDoSign(const unsigned char* dgst, int dlen, DSA* dsa) { |
| 356 int dlen, | |
| 357 DSA* dsa) { | |
| 358 // Extract the JNI reference to the PrivateKey object. | 353 // Extract the JNI reference to the PrivateKey object. |
| 359 jobject private_key = reinterpret_cast<jobject>(DSA_get_ex_data(dsa, 0)); | 354 jobject private_key = reinterpret_cast<jobject>(DSA_get_ex_data(dsa, 0)); |
| 360 if (private_key == NULL) | 355 if (private_key == NULL) |
| 361 return NULL; | 356 return NULL; |
| 362 | 357 |
| 363 // Sign the message with it, calling platform APIs. | 358 // Sign the message with it, calling platform APIs. |
| 364 std::vector<uint8> signature; | 359 std::vector<uint8> signature; |
| 365 if (!RawSignDigestWithPrivateKey( | 360 if (!RawSignDigestWithPrivateKey( |
| 366 private_key, | 361 private_key, |
| 367 base::StringPiece( | 362 base::StringPiece(reinterpret_cast<const char*>(dgst), |
| 368 reinterpret_cast<const char*>(dgst), | 363 static_cast<size_t>(dlen)), |
| 369 static_cast<size_t>(dlen)), | |
| 370 &signature)) { | 364 &signature)) { |
| 371 return NULL; | 365 return NULL; |
| 372 } | 366 } |
| 373 | 367 |
| 374 // Note: With DSA, the actual signature might be smaller than DSA_size(). | 368 // Note: With DSA, the actual signature might be smaller than DSA_size(). |
| 375 size_t max_expected_size = static_cast<size_t>(DSA_size(dsa)); | 369 size_t max_expected_size = static_cast<size_t>(DSA_size(dsa)); |
| 376 if (signature.size() > max_expected_size) { | 370 if (signature.size() > max_expected_size) { |
| 377 LOG(ERROR) << "DSA Signature size mismatch, actual: " | 371 LOG(ERROR) << "DSA Signature size mismatch, actual: " << signature.size() |
| 378 << signature.size() << ", expected <= " | 372 << ", expected <= " << max_expected_size; |
| 379 << max_expected_size; | |
| 380 return NULL; | 373 return NULL; |
| 381 } | 374 } |
| 382 | 375 |
| 383 // Convert the signature into a DSA_SIG object. | 376 // Convert the signature into a DSA_SIG object. |
| 384 const unsigned char* sigbuf = | 377 const unsigned char* sigbuf = |
| 385 reinterpret_cast<const unsigned char*>(&signature[0]); | 378 reinterpret_cast<const unsigned char*>(&signature[0]); |
| 386 int siglen = static_cast<size_t>(signature.size()); | 379 int siglen = static_cast<size_t>(signature.size()); |
| 387 DSA_SIG* dsa_sig = d2i_DSA_SIG(NULL, &sigbuf, siglen); | 380 DSA_SIG* dsa_sig = d2i_DSA_SIG(NULL, &sigbuf, siglen); |
| 388 return dsa_sig; | 381 return dsa_sig; |
| 389 } | 382 } |
| 390 | 383 |
| 391 int DsaMethodSignSetup(DSA* dsa, | 384 int DsaMethodSignSetup(DSA* dsa, BN_CTX* ctx_in, BIGNUM** kinvp, BIGNUM** rp) { |
| 392 BN_CTX* ctx_in, | |
| 393 BIGNUM** kinvp, | |
| 394 BIGNUM** rp) { | |
| 395 NOTIMPLEMENTED(); | 385 NOTIMPLEMENTED(); |
| 396 DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_INVALID_DIGEST_TYPE); | 386 DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_INVALID_DIGEST_TYPE); |
| 397 return -1; | 387 return -1; |
| 398 } | 388 } |
| 399 | 389 |
| 400 int DsaMethodDoVerify(const unsigned char* dgst, | 390 int DsaMethodDoVerify(const unsigned char* dgst, |
| 401 int dgst_len, | 391 int dgst_len, |
| 402 DSA_SIG* sig, | 392 DSA_SIG* sig, |
| 403 DSA* dsa) { | 393 DSA* dsa) { |
| 404 NOTIMPLEMENTED(); | 394 NOTIMPLEMENTED(); |
| 405 DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_INVALID_DIGEST_TYPE); | 395 DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_INVALID_DIGEST_TYPE); |
| 406 return -1; | 396 return -1; |
| 407 } | 397 } |
| 408 | 398 |
| 409 int DsaMethodFinish(DSA* dsa) { | 399 int DsaMethodFinish(DSA* dsa) { |
| 410 // Free the global JNI reference that was created with this | 400 // Free the global JNI reference that was created with this |
| 411 // wrapper key. | 401 // wrapper key. |
| 412 jobject key = reinterpret_cast<jobject>(DSA_get_ex_data(dsa,0)); | 402 jobject key = reinterpret_cast<jobject>(DSA_get_ex_data(dsa, 0)); |
| 413 if (key != NULL) { | 403 if (key != NULL) { |
| 414 DSA_set_ex_data(dsa, 0, NULL); | 404 DSA_set_ex_data(dsa, 0, NULL); |
| 415 ReleaseKey(key); | 405 ReleaseKey(key); |
| 416 } | 406 } |
| 417 // Actual return value is ignored by OpenSSL. There are no docs | 407 // Actual return value is ignored by OpenSSL. There are no docs |
| 418 // explaining what this is supposed to be. | 408 // explaining what this is supposed to be. |
| 419 return 0; | 409 return 0; |
| 420 } | 410 } |
| 421 | 411 |
| 422 const DSA_METHOD android_dsa_method = { | 412 const DSA_METHOD android_dsa_method = { |
| 423 /* .name = */ "Android signing-only DSA method", | 413 /* .name = */ "Android signing-only DSA method", |
| 424 /* .dsa_do_sign = */ DsaMethodDoSign, | 414 /* .dsa_do_sign = */ DsaMethodDoSign, |
| 425 /* .dsa_sign_setup = */ DsaMethodSignSetup, | 415 /* .dsa_sign_setup = */ DsaMethodSignSetup, |
| 426 /* .dsa_do_verify = */ DsaMethodDoVerify, | 416 /* .dsa_do_verify = */ DsaMethodDoVerify, |
| 427 /* .dsa_mod_exp = */ NULL, | 417 /* .dsa_mod_exp = */ NULL, |
| 428 /* .bn_mod_exp = */ NULL, | 418 /* .bn_mod_exp = */ NULL, |
| 429 /* .init = */ NULL, // nothing to do here. | 419 /* .init = */ NULL, // nothing to do here. |
| 430 /* .finish = */ DsaMethodFinish, | 420 /* .finish = */ DsaMethodFinish, |
| 431 /* .flags = */ 0, | 421 /* .flags = */ 0, |
| 432 /* .app_data = */ NULL, | 422 /* .app_data = */ NULL, |
| 433 /* .dsa_paramgem = */ NULL, | 423 /* .dsa_paramgem = */ NULL, |
| 434 /* .dsa_keygen = */ NULL | 424 /* .dsa_keygen = */ NULL}; |
| 435 }; | |
| 436 | 425 |
| 437 // Setup an EVP_PKEY to wrap an existing DSA platform PrivateKey object. | 426 // Setup an EVP_PKEY to wrap an existing DSA platform PrivateKey object. |
| 438 // |private_key| is a JNI reference (local or global) to the object. | 427 // |private_key| is a JNI reference (local or global) to the object. |
| 439 // |pkey| is the EVP_PKEY to setup as a wrapper. | 428 // |pkey| is the EVP_PKEY to setup as a wrapper. |
| 440 // Returns true on success, false otherwise. | 429 // Returns true on success, false otherwise. |
| 441 // On success, this creates a global JNI reference to the same object | 430 // On success, this creates a global JNI reference to the same object |
| 442 // that will be owned by and destroyed with the EVP_PKEY. | 431 // that will be owned by and destroyed with the EVP_PKEY. |
| 443 bool GetDsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { | 432 bool GetDsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { |
| 444 ScopedDSA dsa(DSA_new()); | 433 ScopedDSA dsa(DSA_new()); |
| 445 DSA_set_method(dsa.get(), &android_dsa_method); | 434 DSA_set_method(dsa.get(), &android_dsa_method); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 // This callback shall never be called with the current OpenSSL | 492 // This callback shall never be called with the current OpenSSL |
| 504 // implementation (the library only ever duplicates EX_DATA items | 493 // implementation (the library only ever duplicates EX_DATA items |
| 505 // for SSL and BIO objects). But provide this to catch regressions | 494 // for SSL and BIO objects). But provide this to catch regressions |
| 506 // in the future. | 495 // in the future. |
| 507 CHECK(false) << "ExDataDup was called for ECDSA custom key !?"; | 496 CHECK(false) << "ExDataDup was called for ECDSA custom key !?"; |
| 508 // Return value is currently ignored by OpenSSL. | 497 // Return value is currently ignored by OpenSSL. |
| 509 return 0; | 498 return 0; |
| 510 } | 499 } |
| 511 | 500 |
| 512 class EcdsaExDataIndex { | 501 class EcdsaExDataIndex { |
| 513 public: | 502 public: |
| 514 int ex_data_index() { return ex_data_index_; } | 503 int ex_data_index() { return ex_data_index_; } |
| 515 | 504 |
| 516 EcdsaExDataIndex() { | 505 EcdsaExDataIndex() { |
| 517 ex_data_index_ = ECDSA_get_ex_new_index(0, // argl | 506 ex_data_index_ = ECDSA_get_ex_new_index(0, // argl |
| 518 NULL, // argp | 507 NULL, // argp |
| 519 NULL, // new_func | 508 NULL, // new_func |
| 520 ExDataDup, // dup_func | 509 ExDataDup, // dup_func |
| 521 ExDataFree); // free_func | 510 ExDataFree); // free_func |
| 522 } | 511 } |
| 523 | 512 |
| 524 private: | 513 private: |
| 525 int ex_data_index_; | 514 int ex_data_index_; |
| 526 }; | 515 }; |
| 527 | 516 |
| 528 // Returns the index of the custom EX_DATA used to store the JNI reference. | 517 // Returns the index of the custom EX_DATA used to store the JNI reference. |
| 529 int EcdsaGetExDataIndex(void) { | 518 int EcdsaGetExDataIndex(void) { |
| 530 // Use a LazyInstance to perform thread-safe lazy initialization. | 519 // Use a LazyInstance to perform thread-safe lazy initialization. |
| 531 // Use a leaky one, since OpenSSL doesn't provide a way to release | 520 // Use a leaky one, since OpenSSL doesn't provide a way to release |
| 532 // allocated EX_DATA indices. | 521 // allocated EX_DATA indices. |
| 533 static base::LazyInstance<EcdsaExDataIndex>::Leaky s_instance = | 522 static base::LazyInstance<EcdsaExDataIndex>::Leaky s_instance = |
| 534 LAZY_INSTANCE_INITIALIZER; | 523 LAZY_INSTANCE_INITIALIZER; |
| 535 return s_instance.Get().ex_data_index(); | 524 return s_instance.Get().ex_data_index(); |
| 536 } | 525 } |
| 537 | 526 |
| 538 ECDSA_SIG* EcdsaMethodDoSign(const unsigned char* dgst, | 527 ECDSA_SIG* EcdsaMethodDoSign(const unsigned char* dgst, |
| 539 int dgst_len, | 528 int dgst_len, |
| 540 const BIGNUM* inv, | 529 const BIGNUM* inv, |
| 541 const BIGNUM* rp, | 530 const BIGNUM* rp, |
| 542 EC_KEY* eckey) { | 531 EC_KEY* eckey) { |
| 543 // Retrieve private key JNI reference. | 532 // Retrieve private key JNI reference. |
| 544 jobject private_key = reinterpret_cast<jobject>( | 533 jobject private_key = reinterpret_cast<jobject>( |
| 545 ECDSA_get_ex_data(eckey, EcdsaGetExDataIndex())); | 534 ECDSA_get_ex_data(eckey, EcdsaGetExDataIndex())); |
| 546 if (!private_key) { | 535 if (!private_key) { |
| 547 LOG(WARNING) << "Null JNI reference passed to EcdsaMethodDoSign!"; | 536 LOG(WARNING) << "Null JNI reference passed to EcdsaMethodDoSign!"; |
| 548 return NULL; | 537 return NULL; |
| 549 } | 538 } |
| 550 // Sign message with it through JNI. | 539 // Sign message with it through JNI. |
| 551 std::vector<uint8> signature; | 540 std::vector<uint8> signature; |
| 552 base::StringPiece digest( | 541 base::StringPiece digest(reinterpret_cast<const char*>(dgst), |
| 553 reinterpret_cast<const char*>(dgst), | 542 static_cast<size_t>(dgst_len)); |
| 554 static_cast<size_t>(dgst_len)); | 543 if (!RawSignDigestWithPrivateKey(private_key, digest, &signature)) { |
| 555 if (!RawSignDigestWithPrivateKey( | |
| 556 private_key, digest, &signature)) { | |
| 557 LOG(WARNING) << "Could not sign message in EcdsaMethodDoSign!"; | 544 LOG(WARNING) << "Could not sign message in EcdsaMethodDoSign!"; |
| 558 return NULL; | 545 return NULL; |
| 559 } | 546 } |
| 560 | 547 |
| 561 // Note: With ECDSA, the actual signature may be smaller than | 548 // Note: With ECDSA, the actual signature may be smaller than |
| 562 // ECDSA_size(). | 549 // ECDSA_size(). |
| 563 size_t max_expected_size = static_cast<size_t>(ECDSA_size(eckey)); | 550 size_t max_expected_size = static_cast<size_t>(ECDSA_size(eckey)); |
| 564 if (signature.size() > max_expected_size) { | 551 if (signature.size() > max_expected_size) { |
| 565 LOG(ERROR) << "ECDSA Signature size mismatch, actual: " | 552 LOG(ERROR) << "ECDSA Signature size mismatch, actual: " << signature.size() |
| 566 << signature.size() << ", expected <= " | 553 << ", expected <= " << max_expected_size; |
| 567 << max_expected_size; | |
| 568 return NULL; | 554 return NULL; |
| 569 } | 555 } |
| 570 | 556 |
| 571 // Convert signature to ECDSA_SIG object | 557 // Convert signature to ECDSA_SIG object |
| 572 const unsigned char* sigbuf = | 558 const unsigned char* sigbuf = |
| 573 reinterpret_cast<const unsigned char*>(&signature[0]); | 559 reinterpret_cast<const unsigned char*>(&signature[0]); |
| 574 long siglen = static_cast<long>(signature.size()); | 560 long siglen = static_cast<long>(signature.size()); |
| 575 return d2i_ECDSA_SIG(NULL, &sigbuf, siglen); | 561 return d2i_ECDSA_SIG(NULL, &sigbuf, siglen); |
| 576 } | 562 } |
| 577 | 563 |
| 578 int EcdsaMethodSignSetup(EC_KEY* eckey, | 564 int EcdsaMethodSignSetup(EC_KEY* eckey, |
| 579 BN_CTX* ctx, | 565 BN_CTX* ctx, |
| 580 BIGNUM** kinv, | 566 BIGNUM** kinv, |
| 581 BIGNUM** r) { | 567 BIGNUM** r) { |
| 582 NOTIMPLEMENTED(); | 568 NOTIMPLEMENTED(); |
| 583 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ECDSA_R_ERR_EC_LIB); | 569 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ECDSA_R_ERR_EC_LIB); |
| 584 return -1; | 570 return -1; |
| 585 } | 571 } |
| 586 | 572 |
| 587 int EcdsaMethodDoVerify(const unsigned char* dgst, | 573 int EcdsaMethodDoVerify(const unsigned char* dgst, |
| 588 int dgst_len, | 574 int dgst_len, |
| 589 const ECDSA_SIG* sig, | 575 const ECDSA_SIG* sig, |
| 590 EC_KEY* eckey) { | 576 EC_KEY* eckey) { |
| 591 NOTIMPLEMENTED(); | 577 NOTIMPLEMENTED(); |
| 592 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_ERR_EC_LIB); | 578 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_ERR_EC_LIB); |
| 593 return -1; | 579 return -1; |
| 594 } | 580 } |
| 595 | 581 |
| 596 const ECDSA_METHOD android_ecdsa_method = { | 582 const ECDSA_METHOD android_ecdsa_method = { |
| 597 /* .name = */ "Android signing-only ECDSA method", | 583 /* .name = */ "Android signing-only ECDSA method", |
| 598 /* .ecdsa_do_sign = */ EcdsaMethodDoSign, | 584 /* .ecdsa_do_sign = */ EcdsaMethodDoSign, |
| 599 /* .ecdsa_sign_setup = */ EcdsaMethodSignSetup, | 585 /* .ecdsa_sign_setup = */ EcdsaMethodSignSetup, |
| 600 /* .ecdsa_do_verify = */ EcdsaMethodDoVerify, | 586 /* .ecdsa_do_verify = */ EcdsaMethodDoVerify, |
| 601 /* .flags = */ 0, | 587 /* .flags = */ 0, |
| 602 /* .app_data = */ NULL, | 588 /* .app_data = */ NULL, |
| 603 }; | 589 }; |
| 604 | 590 |
| 605 // Setup an EVP_PKEY to wrap an existing platform PrivateKey object. | 591 // Setup an EVP_PKEY to wrap an existing platform PrivateKey object. |
| 606 // |private_key| is the JNI reference (local or global) to the object. | 592 // |private_key| is the JNI reference (local or global) to the object. |
| 607 // |pkey| is the EVP_PKEY to setup as a wrapper. | 593 // |pkey| is the EVP_PKEY to setup as a wrapper. |
| 608 // Returns true on success, false otherwise. | 594 // Returns true on success, false otherwise. |
| 609 // On success, this creates a global JNI reference to the object that | 595 // On success, this creates a global JNI reference to the object that |
| 610 // is owned by and destroyed with the EVP_PKEY. I.e. the caller shall | 596 // is owned by and destroyed with the EVP_PKEY. I.e. the caller shall |
| 611 // always free |private_key| after the call. | 597 // always free |private_key| after the call. |
| 612 bool GetEcdsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { | 598 bool GetEcdsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 630 return false; | 616 return false; |
| 631 } | 617 } |
| 632 EC_KEY_set_group(eckey.get(), group.release()); | 618 EC_KEY_set_group(eckey.get(), group.release()); |
| 633 | 619 |
| 634 ScopedJavaGlobalRef<jobject> global_key; | 620 ScopedJavaGlobalRef<jobject> global_key; |
| 635 global_key.Reset(NULL, private_key); | 621 global_key.Reset(NULL, private_key); |
| 636 if (global_key.is_null()) { | 622 if (global_key.is_null()) { |
| 637 LOG(ERROR) << "Can't create global JNI reference"; | 623 LOG(ERROR) << "Can't create global JNI reference"; |
| 638 return false; | 624 return false; |
| 639 } | 625 } |
| 640 ECDSA_set_ex_data(eckey.get(), | 626 ECDSA_set_ex_data(eckey.get(), EcdsaGetExDataIndex(), global_key.Release()); |
| 641 EcdsaGetExDataIndex(), | |
| 642 global_key.Release()); | |
| 643 | 627 |
| 644 EVP_PKEY_assign_EC_KEY(pkey, eckey.release()); | 628 EVP_PKEY_assign_EC_KEY(pkey, eckey.release()); |
| 645 return true; | 629 return true; |
| 646 } | 630 } |
| 647 | 631 |
| 648 } // namespace | 632 } // namespace |
| 649 | 633 |
| 650 EVP_PKEY* GetOpenSSLPrivateKeyWrapper(jobject private_key) { | 634 EVP_PKEY* GetOpenSSLPrivateKeyWrapper(jobject private_key) { |
| 651 // Create new empty EVP_PKEY instance. | 635 // Create new empty EVP_PKEY instance. |
| 652 ScopedEVP_PKEY pkey(EVP_PKEY_new()); | 636 ScopedEVP_PKEY pkey(EVP_PKEY_new()); |
| 653 if (!pkey.get()) | 637 if (!pkey.get()) |
| 654 return NULL; | 638 return NULL; |
| 655 | 639 |
| 656 // Create sub key type, depending on private key's algorithm type. | 640 // Create sub key type, depending on private key's algorithm type. |
| 657 PrivateKeyType key_type = GetPrivateKeyType(private_key); | 641 PrivateKeyType key_type = GetPrivateKeyType(private_key); |
| 658 switch (key_type) { | 642 switch (key_type) { |
| 659 case PRIVATE_KEY_TYPE_RSA: | 643 case PRIVATE_KEY_TYPE_RSA: { |
| 660 { | 644 // Route around platform bug: if Android < 4.2, then |
| 661 // Route around platform bug: if Android < 4.2, then | 645 // base::android::RawSignDigestWithPrivateKey() cannot work, so |
| 662 // base::android::RawSignDigestWithPrivateKey() cannot work, so | 646 // instead, obtain a raw EVP_PKEY* to the system object |
| 663 // instead, obtain a raw EVP_PKEY* to the system object | 647 // backing this PrivateKey object. |
| 664 // backing this PrivateKey object. | 648 const int kAndroid42ApiLevel = 17; |
| 665 const int kAndroid42ApiLevel = 17; | 649 if (base::android::BuildInfo::GetInstance()->sdk_int() < |
| 666 if (base::android::BuildInfo::GetInstance()->sdk_int() < | 650 kAndroid42ApiLevel) { |
| 667 kAndroid42ApiLevel) { | 651 EVP_PKEY* legacy_key = GetRsaLegacyKey(private_key); |
| 668 EVP_PKEY* legacy_key = GetRsaLegacyKey(private_key); | 652 if (legacy_key == NULL) |
| 669 if (legacy_key == NULL) | 653 return NULL; |
| 670 return NULL; | 654 pkey.reset(legacy_key); |
| 671 pkey.reset(legacy_key); | 655 } else { |
| 672 } else { | 656 // Running on Android 4.2. |
| 673 // Running on Android 4.2. | 657 if (!GetRsaPkeyWrapper(private_key, pkey.get())) |
| 674 if (!GetRsaPkeyWrapper(private_key, pkey.get())) | 658 return NULL; |
| 675 return NULL; | |
| 676 } | |
| 677 } | 659 } |
| 678 break; | 660 } break; |
| 679 case PRIVATE_KEY_TYPE_DSA: | 661 case PRIVATE_KEY_TYPE_DSA: |
| 680 if (!GetDsaPkeyWrapper(private_key, pkey.get())) | 662 if (!GetDsaPkeyWrapper(private_key, pkey.get())) |
| 681 return NULL; | 663 return NULL; |
| 682 break; | 664 break; |
| 683 case PRIVATE_KEY_TYPE_ECDSA: | 665 case PRIVATE_KEY_TYPE_ECDSA: |
| 684 if (!GetEcdsaPkeyWrapper(private_key, pkey.get())) | 666 if (!GetEcdsaPkeyWrapper(private_key, pkey.get())) |
| 685 return NULL; | 667 return NULL; |
| 686 break; | 668 break; |
| 687 default: | 669 default: |
| 688 LOG(WARNING) | 670 LOG(WARNING) |
| 689 << "GetOpenSSLPrivateKeyWrapper() called with invalid key type"; | 671 << "GetOpenSSLPrivateKeyWrapper() called with invalid key type"; |
| 690 return NULL; | 672 return NULL; |
| 691 } | 673 } |
| 692 return pkey.release(); | 674 return pkey.release(); |
| 693 } | 675 } |
| 694 | 676 |
| 695 } // namespace android | 677 } // namespace android |
| 696 } // namespace net | 678 } // namespace net |
| OLD | NEW |