Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: content/renderer/webcrypto/webcrypto_impl_nss.cc

Issue 68303009: [webcrypto] Add RSASSA-PKCS1-v1_5 sign and verify for NSS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase plus minor fix Created 6 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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 "content/renderer/webcrypto/webcrypto_impl.h" 5 #include "content/renderer/webcrypto/webcrypto_impl.h"
6 6
7 #include <cryptohi.h> 7 #include <cryptohi.h>
8 #include <pk11pub.h> 8 #include <pk11pub.h>
9 #include <sechash.h> 9 #include <sechash.h>
10 10
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 case blink::WebCryptoAlgorithmIdHmac: 238 case blink::WebCryptoAlgorithmIdHmac:
239 case blink::WebCryptoAlgorithmIdAesCbc: 239 case blink::WebCryptoAlgorithmIdAesCbc:
240 case blink::WebCryptoAlgorithmIdAesKw: 240 case blink::WebCryptoAlgorithmIdAesKw:
241 type = blink::WebCryptoKeyTypeSecret; 241 type = blink::WebCryptoKeyTypeSecret;
242 break; 242 break;
243 // TODO(bryaneyler): Support more key types. 243 // TODO(bryaneyler): Support more key types.
244 default: 244 default:
245 return false; 245 return false;
246 } 246 }
247 247
248 // TODO(bryaneyler): Need to split handling for symmetric and asymmetric keys.
249 // Currently only supporting symmetric.
248 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; 250 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
249 // Flags are verified at the Blink layer; here the flags are set to all 251 // Flags are verified at the Blink layer; here the flags are set to all
250 // possible operations for this key type. 252 // possible operations for this key type.
251 CK_FLAGS flags = 0; 253 CK_FLAGS flags = 0;
252 254
253 switch (algorithm.id()) { 255 switch (algorithm.id()) {
254 case blink::WebCryptoAlgorithmIdHmac: { 256 case blink::WebCryptoAlgorithmIdHmac: {
255 const blink::WebCryptoHmacParams* params = algorithm.hmacParams(); 257 const blink::WebCryptoHmacParams* params = algorithm.hmacParams();
256 if (!params) { 258 if (!params) {
257 return false; 259 return false;
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 return false; 844 return false;
843 } 845 }
844 } 846 }
845 847
846 bool WebCryptoImpl::SignInternal( 848 bool WebCryptoImpl::SignInternal(
847 const blink::WebCryptoAlgorithm& algorithm, 849 const blink::WebCryptoAlgorithm& algorithm,
848 const blink::WebCryptoKey& key, 850 const blink::WebCryptoKey& key,
849 const unsigned char* data, 851 const unsigned char* data,
850 unsigned data_size, 852 unsigned data_size,
851 blink::WebArrayBuffer* buffer) { 853 blink::WebArrayBuffer* buffer) {
854
855 // Note: It is not an error to sign empty data.
856
857 DCHECK(buffer);
858 DCHECK_NE(0, key.usages() & blink::WebCryptoKeyUsageSign);
859
852 blink::WebArrayBuffer result; 860 blink::WebArrayBuffer result;
853 861
854 switch (algorithm.id()) { 862 switch (algorithm.id()) {
855 case blink::WebCryptoAlgorithmIdHmac: { 863 case blink::WebCryptoAlgorithmIdHmac: {
856 const blink::WebCryptoHmacParams* params = algorithm.hmacParams(); 864 const blink::WebCryptoHmacParams* params = algorithm.hmacParams();
857 if (!params) { 865 if (!params) {
858 return false; 866 return false;
859 } 867 }
860 868
861 SymKeyHandle* sym_key = reinterpret_cast<SymKeyHandle*>(key.handle()); 869 SymKeyHandle* sym_key = reinterpret_cast<SymKeyHandle*>(key.handle());
862 870
863 DCHECK_EQ(PK11_GetMechanism(sym_key->key()), 871 DCHECK_EQ(PK11_GetMechanism(sym_key->key()),
864 WebCryptoHashToHMACMechanism(params->hash())); 872 WebCryptoHashToHMACMechanism(params->hash()));
865 DCHECK_NE(0, key.usages() & blink::WebCryptoKeyUsageSign);
866 873
867 SECItem param_item = { siBuffer, NULL, 0 }; 874 SECItem param_item = { siBuffer, NULL, 0 };
868 SECItem data_item = { 875 SECItem data_item = {
869 siBuffer, 876 siBuffer,
870 const_cast<unsigned char*>(data), 877 const_cast<unsigned char*>(data),
871 data_size 878 data_size
872 }; 879 };
873 // First call is to figure out the length. 880 // First call is to figure out the length.
874 SECItem signature_item = { siBuffer, NULL, 0 }; 881 SECItem signature_item = { siBuffer, NULL, 0 };
875 882
(...skipping 17 matching lines...) Expand all
893 &signature_item, 900 &signature_item,
894 &data_item) != SECSuccess) { 901 &data_item) != SECSuccess) {
895 NOTREACHED(); 902 NOTREACHED();
896 return false; 903 return false;
897 } 904 }
898 905
899 DCHECK_EQ(result.byteLength(), signature_item.len); 906 DCHECK_EQ(result.byteLength(), signature_item.len);
900 907
901 break; 908 break;
902 } 909 }
910 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: {
911 if (key.type() != blink::WebCryptoKeyTypePrivate ||
912 webcrypto::GetInnerHashAlgorithm(algorithm).isNull())
913 return false;
914
915 PrivateKeyHandle* const private_key =
916 reinterpret_cast<PrivateKeyHandle*>(key.handle());
917 DCHECK(private_key);
918 DCHECK(private_key->key());
919
920 // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the
921 // inner hash of the input Web Crypto algorithm.
922 SECOidTag sign_alg_tag;
923 switch (webcrypto::GetInnerHashAlgorithm(algorithm).id()) {
924 case blink::WebCryptoAlgorithmIdSha1:
925 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
926 break;
927 case blink::WebCryptoAlgorithmIdSha224:
928 sign_alg_tag = SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION;
929 break;
930 case blink::WebCryptoAlgorithmIdSha256:
931 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
932 break;
933 case blink::WebCryptoAlgorithmIdSha384:
934 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
935 break;
936 case blink::WebCryptoAlgorithmIdSha512:
937 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
938 break;
939 default:
940 return false;
941 }
942
943 crypto::ScopedSECItem signature_item(SECITEM_AllocItem(NULL, NULL, 0));
944 if (SEC_SignData(signature_item.get(),
945 data,
946 data_size,
947 private_key->key(),
948 sign_alg_tag) != SECSuccess) {
949 return false;
950 }
951
952 result = webcrypto::CreateArrayBuffer(signature_item->data,
953 signature_item->len);
954
955 break;
956 }
903 default: 957 default:
904 return false; 958 return false;
905 } 959 }
906 960
907 *buffer = result; 961 *buffer = result;
908 return true; 962 return true;
909 } 963 }
910 964
911 bool WebCryptoImpl::VerifySignatureInternal( 965 bool WebCryptoImpl::VerifySignatureInternal(
912 const blink::WebCryptoAlgorithm& algorithm, 966 const blink::WebCryptoAlgorithm& algorithm,
913 const blink::WebCryptoKey& key, 967 const blink::WebCryptoKey& key,
914 const unsigned char* signature, 968 const unsigned char* signature,
915 unsigned signature_size, 969 unsigned signature_size,
916 const unsigned char* data, 970 const unsigned char* data,
917 unsigned data_size, 971 unsigned data_size,
918 bool* signature_match) { 972 bool* signature_match) {
973
974 if (!signature_size)
975 return false;
976 DCHECK(signature);
977
919 switch (algorithm.id()) { 978 switch (algorithm.id()) {
920 case blink::WebCryptoAlgorithmIdHmac: { 979 case blink::WebCryptoAlgorithmIdHmac: {
921 blink::WebArrayBuffer result; 980 blink::WebArrayBuffer result;
922 if (!SignInternal(algorithm, key, data, data_size, &result)) { 981 if (!SignInternal(algorithm, key, data, data_size, &result)) {
923 return false; 982 return false;
924 } 983 }
925 984
926 // Handling of truncated signatures is underspecified in the WebCrypto 985 // Handling of truncated signatures is underspecified in the WebCrypto
927 // spec, so here we fail verification if a truncated signature is being 986 // spec, so here we fail verification if a truncated signature is being
928 // verified. 987 // verified.
929 // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=23097 988 // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=23097
930 *signature_match = 989 *signature_match =
931 result.byteLength() == signature_size && 990 result.byteLength() == signature_size &&
932 crypto::SecureMemEqual(result.data(), signature, signature_size); 991 crypto::SecureMemEqual(result.data(), signature, signature_size);
933 992
934 break; 993 break;
935 } 994 }
995 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: {
996 if (key.type() != blink::WebCryptoKeyTypePublic)
997 return false;
998
999 PublicKeyHandle* const public_key =
1000 reinterpret_cast<PublicKeyHandle*>(key.handle());
1001 DCHECK(public_key);
1002 DCHECK(public_key->key());
1003
1004 const SECItem signature_item = {
1005 siBuffer,
1006 const_cast<unsigned char*>(signature),
1007 signature_size
1008 };
1009
1010 SECOidTag hash_alg_tag;
1011 switch (webcrypto::GetInnerHashAlgorithm(algorithm).id()) {
1012 case blink::WebCryptoAlgorithmIdSha1:
1013 hash_alg_tag = SEC_OID_SHA1;
1014 break;
1015 case blink::WebCryptoAlgorithmIdSha224:
1016 hash_alg_tag = SEC_OID_SHA224;
1017 break;
1018 case blink::WebCryptoAlgorithmIdSha256:
1019 hash_alg_tag = SEC_OID_SHA256;
1020 break;
1021 case blink::WebCryptoAlgorithmIdSha384:
1022 hash_alg_tag = SEC_OID_SHA384;
1023 break;
1024 case blink::WebCryptoAlgorithmIdSha512:
1025 hash_alg_tag = SEC_OID_SHA512;
1026 break;
1027 default:
1028 return false;
1029 }
1030
1031 *signature_match =
1032 SECSuccess == VFY_VerifyDataDirect(data,
1033 data_size,
1034 public_key->key(),
1035 &signature_item,
1036 SEC_OID_PKCS1_RSA_ENCRYPTION,
1037 hash_alg_tag,
1038 NULL,
1039 NULL);
1040
1041 break;
1042 }
936 default: 1043 default:
937 return false; 1044 return false;
938 } 1045 }
939 1046
940 return true; 1047 return true;
941 } 1048 }
942 1049
943 bool WebCryptoImpl::ImportRsaPublicKeyInternal( 1050 bool WebCryptoImpl::ImportRsaPublicKeyInternal(
944 const unsigned char* modulus_data, 1051 const unsigned char* modulus_data,
945 unsigned modulus_size, 1052 unsigned modulus_size,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 1099
993 *key = blink::WebCryptoKey::create(new PublicKeyHandle(pubkey.Pass()), 1100 *key = blink::WebCryptoKey::create(new PublicKeyHandle(pubkey.Pass()),
994 blink::WebCryptoKeyTypePublic, 1101 blink::WebCryptoKeyTypePublic,
995 extractable, 1102 extractable,
996 algorithm, 1103 algorithm,
997 usage_mask); 1104 usage_mask);
998 return true; 1105 return true;
999 } 1106 }
1000 1107
1001 } // namespace content 1108 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698