15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/ec_signature_creator.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/ec_private_key.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/signature_verifier.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// TODO(rch): Add some exported keys from each to
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// test interop between NSS and OpenSSL.
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ECSignatureCreatorTest, BasicTest) {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do a verify round trip.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<crypto::ECPrivateKey> key_original(
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      crypto::ECPrivateKey::Create());
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(key_original.get());
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<uint8> key_info;
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      key_original->ExportEncryptedPrivateKey(std::string(), 1000, &key_info));
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<uint8> pubkey_info;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(key_original->ExportPublicKey(&pubkey_info));
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<crypto::ECPrivateKey> key(
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          std::string(), key_info, pubkey_info));
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(key.get());
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(key->key() != NULL);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<crypto::ECSignatureCreator> signer(
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      crypto::ECSignatureCreator::Create(key.get()));
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(signer.get());
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string data("Hello, World!");
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<uint8> signature;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(signer->Sign(reinterpret_cast<const uint8*>(data.c_str()),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           data.size(),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           &signature));
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<uint8> public_key_info;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(key_original->ExportPublicKey(&public_key_info));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // This is the algorithm ID for ECDSA with SHA-256. Parameters are ABSENT.
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // RFC 5758:
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //        us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   ...
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   When the ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   ecdsa-with-SHA512 algorithm identifier appears in the algorithm field
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   as an AlgorithmIdentifier, the encoding MUST omit the parameters
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   field.  That is, the AlgorithmIdentifier SHALL be a SEQUENCE of one
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   component, the OID ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   SHA384, or ecdsa-with-SHA512.
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // See also RFC 5480, Appendix A.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint8 kECDSAWithSHA256AlgorithmID[] = {
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    0x30, 0x0a,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x06, 0x08,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  crypto::SignatureVerifier verifier;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(verifier.VerifyInit(
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kECDSAWithSHA256AlgorithmID, sizeof(kECDSAWithSHA256AlgorithmID),
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &signature[0], signature.size(),
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &public_key_info.front(), public_key_info.size()));
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  verifier.VerifyUpdate(reinterpret_cast<const uint8*>(data.c_str()),
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        data.size());
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(verifier.VerifyFinal());
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
76