15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file. 45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <cryptohi.h> 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/webcrypto/crypto_data.h" 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/webcrypto/nss/key_nss.h" 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/webcrypto/nss/rsa_key_nss.h" 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/webcrypto/nss/util_nss.h" 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/child/webcrypto/status.h" 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "crypto/scoped_nss_types.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace content { 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace webcrypto { 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace { 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class RsaSsaImplementation : public RsaHashedAlgorithm { 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public: 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RsaSsaImplementation() 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : RsaHashedAlgorithm(CKF_SIGN | CKF_VERIFY, 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blink::WebCryptoKeyUsageVerify, 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blink::WebCryptoKeyUsageSign) {} 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual const char* GetJwkAlgorithm( 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const blink::WebCryptoAlgorithmId hash) const OVERRIDE { 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) switch (hash) { 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case blink::WebCryptoAlgorithmIdSha1: 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return "RS1"; 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case blink::WebCryptoAlgorithmIdSha256: 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return "RS256"; 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case blink::WebCryptoAlgorithmIdSha384: 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return "RS384"; 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case blink::WebCryptoAlgorithmIdSha512: 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return "RS512"; 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default: 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return NULL; 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual Status Sign(const blink::WebCryptoAlgorithm& algorithm, 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const blink::WebCryptoKey& key, 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const CryptoData& data, 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<uint8_t>* buffer) const OVERRIDE { 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (key.type() != blink::WebCryptoKeyTypePrivate) 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return Status::ErrorUnexpectedKeyType(); 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SECKEYPrivateKey* private_key = PrivateKeyNss::Cast(key)->key(); 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const blink::WebCryptoAlgorithm& hash = 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) key.algorithm().rsaHashedParams()->hash(); 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // inner hash of the input Web Crypto algorithm. 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SECOidTag sign_alg_tag; 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) switch (hash.id()) { 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case blink::WebCryptoAlgorithmIdSha1: 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case blink::WebCryptoAlgorithmIdSha256: 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case blink::WebCryptoAlgorithmIdSha384: 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case blink::WebCryptoAlgorithmIdSha512: 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default: 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return Status::ErrorUnsupported(); 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) crypto::ScopedSECItem signature_item(SECITEM_AllocItem(NULL, NULL, 0)); 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (SEC_SignData(signature_item.get(), 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) data.bytes(), 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) data.byte_length(), 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private_key, 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sign_alg_tag) != SECSuccess) { 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return Status::OperationError(); 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) buffer->assign(signature_item->data, 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) signature_item->data + signature_item->len); 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return Status::Success(); 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual Status Verify(const blink::WebCryptoAlgorithm& algorithm, 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const blink::WebCryptoKey& key, 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const CryptoData& signature, 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const CryptoData& data, 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool* signature_match) const OVERRIDE { 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (key.type() != blink::WebCryptoKeyTypePublic) 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return Status::ErrorUnexpectedKeyType(); 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SECKEYPublicKey* public_key = PublicKeyNss::Cast(key)->key(); 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const blink::WebCryptoAlgorithm& hash = 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) key.algorithm().rsaHashedParams()->hash(); 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const SECItem signature_item = MakeSECItemForBuffer(signature); 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SECOidTag hash_alg_tag; 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) switch (hash.id()) { 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case blink::WebCryptoAlgorithmIdSha1: 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hash_alg_tag = SEC_OID_SHA1; 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case blink::WebCryptoAlgorithmIdSha256: 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hash_alg_tag = SEC_OID_SHA256; 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case blink::WebCryptoAlgorithmIdSha384: 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hash_alg_tag = SEC_OID_SHA384; 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case blink::WebCryptoAlgorithmIdSha512: 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hash_alg_tag = SEC_OID_SHA512; 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default: 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return Status::ErrorUnsupported(); 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *signature_match = 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SECSuccess == VFY_VerifyDataDirect(data.bytes(), 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) data.byte_length(), 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public_key, 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &signature_item, 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SEC_OID_PKCS1_RSA_ENCRYPTION, 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hash_alg_tag, 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL, 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL); 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return Status::Success(); 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)AlgorithmImplementation* CreatePlatformRsaSsaImplementation() { 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return new RsaSsaImplementation; 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace webcrypto 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace content 145