// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/keygen_handler.h"

#include <Security/SecAsn1Coder.h>
#include <Security/SecAsn1Templates.h>
#include <Security/Security.h>

#include "base/base64.h"
#include "base/logging.h"
#include "base/mac/mac_logging.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/string_util.h"
#include "base/synchronization/lock.h"
#include "base/sys_string_conversions.h"
#include "crypto/cssm_init.h"
#include "crypto/mac_security_services_lock.h"

// These are in Security.framework but not declared in a public header.
extern const SecAsn1Template kSecAsn1AlgorithmIDTemplate[];
extern const SecAsn1Template kSecAsn1SubjectPublicKeyInfoTemplate[];

namespace net {

// Declarations of Netscape keygen cert structures for ASN.1 encoding:

struct PublicKeyAndChallenge {
  CSSM_X509_SUBJECT_PUBLIC_KEY_INFO spki;
  CSSM_DATA challenge_string;
};

// This is a copy of the built-in kSecAsn1IA5StringTemplate, but without the
// 'streamable' flag, which was causing bogus data to be written.
const SecAsn1Template kIA5StringTemplate[] = {
    { SEC_ASN1_IA5_STRING, 0, NULL, sizeof(CSSM_DATA) }
};

static const SecAsn1Template kPublicKeyAndChallengeTemplate[] = {
  {
    SEC_ASN1_SEQUENCE,
    0,
    NULL,
    sizeof(PublicKeyAndChallenge)
  },
  {
    SEC_ASN1_INLINE,
    offsetof(PublicKeyAndChallenge, spki),
    kSecAsn1SubjectPublicKeyInfoTemplate
  },
  {
    SEC_ASN1_INLINE,
    offsetof(PublicKeyAndChallenge, challenge_string),
    kIA5StringTemplate
  },
  {
    0
  }
};

struct SignedPublicKeyAndChallenge {
  PublicKeyAndChallenge pkac;
  CSSM_X509_ALGORITHM_IDENTIFIER signature_algorithm;
  CSSM_DATA signature;
};

static const SecAsn1Template kSignedPublicKeyAndChallengeTemplate[] = {
  {
    SEC_ASN1_SEQUENCE,
    0,
    NULL,
    sizeof(SignedPublicKeyAndChallenge)
  },
  {
    SEC_ASN1_INLINE,
    offsetof(SignedPublicKeyAndChallenge, pkac),
    kPublicKeyAndChallengeTemplate
  },
  {
    SEC_ASN1_INLINE,
    offsetof(SignedPublicKeyAndChallenge, signature_algorithm),
    kSecAsn1AlgorithmIDTemplate
  },
  {
    SEC_ASN1_BIT_STRING,
    offsetof(SignedPublicKeyAndChallenge, signature)
  },
  {
    0
  }
};


static OSStatus CreateRSAKeyPair(int size_in_bits,
                                 SecAccessRef initial_access,
                                 SecKeyRef* out_pub_key,
                                 SecKeyRef* out_priv_key);
static OSStatus SignData(CSSM_DATA data,
                         SecKeyRef private_key,
                         CSSM_DATA* signature);

std::string KeygenHandler::GenKeyAndSignChallenge() {
  std::string result;
  OSStatus err;
  SecAccessRef initial_access = NULL;
  SecKeyRef public_key = NULL;
  SecKeyRef private_key = NULL;
  SecAsn1CoderRef coder = NULL;
  CSSM_DATA signature = {0, NULL};

  {
    if (url_.has_host()) {
      // TODO(davidben): Use something like "Key generated for
      // example.com", but localize it.
      base::mac::ScopedCFTypeRef<CFStringRef> label(
          base::SysUTF8ToCFStringRef(url_.host()));
      // Create an initial access object to set the SecAccessRef. This
      // sets a label on the Keychain dialogs. Pass NULL as the second
      // argument to use the default trusted list; only allow the
      // current application to access without user confirmation.
      err = SecAccessCreate(label, NULL, &initial_access);
      // If we fail, just continue without a label.
      if (err)
        crypto::LogCSSMError("SecAccessCreate", err);
    }

    // Create the key-pair.
    err = CreateRSAKeyPair(key_size_in_bits_, initial_access,
                           &public_key, &private_key);
    if (err)
      goto failure;

    // Get the public key data (DER sequence of modulus, exponent).
    CFDataRef key_data = NULL;
    err = SecKeychainItemExport(public_key, kSecFormatBSAFE, 0, NULL,
                                &key_data);
    if (err) {
      crypto::LogCSSMError("SecKeychainItemExpor", err);
      goto failure;
    }
    base::mac::ScopedCFTypeRef<CFDataRef> scoped_key_data(key_data);

    // Create an ASN.1 encoder.
    err = SecAsn1CoderCreate(&coder);
    if (err) {
      crypto::LogCSSMError("SecAsn1CoderCreate", err);
      goto failure;
    }

    // Fill in and DER-encode the PublicKeyAndChallenge:
    SignedPublicKeyAndChallenge spkac;
    memset(&spkac, 0, sizeof(spkac));
    spkac.pkac.spki.algorithm.algorithm = CSSMOID_RSA;
    spkac.pkac.spki.subjectPublicKey.Length =
        CFDataGetLength(key_data) * 8;  // interpreted as a _bit_ count
    spkac.pkac.spki.subjectPublicKey.Data =
        const_cast<uint8_t*>(CFDataGetBytePtr(key_data));
    spkac.pkac.challenge_string.Length = challenge_.length();
    spkac.pkac.challenge_string.Data =
        reinterpret_cast<uint8_t*>(const_cast<char*>(challenge_.data()));

    CSSM_DATA encoded;
    err = SecAsn1EncodeItem(coder, &spkac.pkac,
                            kPublicKeyAndChallengeTemplate, &encoded);
    if (err) {
      crypto::LogCSSMError("SecAsn1EncodeItem", err);
      goto failure;
    }

    // Compute a signature of the result:
    err = SignData(encoded, private_key, &signature);
    if (err)
      goto failure;
    spkac.signature.Data = signature.Data;
    spkac.signature.Length = signature.Length * 8;  // a _bit_ count
    spkac.signature_algorithm.algorithm = CSSMOID_MD5WithRSA;
    // TODO(snej): MD5 is weak. Can we use SHA1 instead?
    // See <https://bugzilla.mozilla.org/show_bug.cgi?id=549460>

    // DER-encode the entire SignedPublicKeyAndChallenge:
    err = SecAsn1EncodeItem(coder, &spkac,
                            kSignedPublicKeyAndChallengeTemplate, &encoded);
    if (err) {
      crypto::LogCSSMError("SecAsn1EncodeItem", err);
      goto failure;
    }

    // Base64 encode the result.
    std::string input(reinterpret_cast<char*>(encoded.Data), encoded.Length);
    base::Base64Encode(input, &result);
  }

 failure:
  if (err)
    OSSTATUS_LOG(ERROR, err) << "SSL Keygen failed!";
  else
    VLOG(1) << "SSL Keygen succeeded! Output is: " << result;

  // Remove keys from keychain if asked to during unit testing:
  if (!stores_key_) {
    if (public_key)
      SecKeychainItemDelete(reinterpret_cast<SecKeychainItemRef>(public_key));
    if (private_key)
      SecKeychainItemDelete(reinterpret_cast<SecKeychainItemRef>(private_key));
  }

  // Clean up:
  free(signature.Data);
  if (coder)
    SecAsn1CoderRelease(coder);
  if (initial_access)
    CFRelease(initial_access);
  if (public_key)
    CFRelease(public_key);
  if (private_key)
    CFRelease(private_key);
  return result;
}


// Create an RSA key pair with size |size_in_bits|. |initial_access|
// is passed as the initial access control list in Keychain. The
// public and private keys are placed in |out_pub_key| and
// |out_priv_key|, respectively.
static OSStatus CreateRSAKeyPair(int size_in_bits,
                                 SecAccessRef initial_access,
                                 SecKeyRef* out_pub_key,
                                 SecKeyRef* out_priv_key) {
  OSStatus err;
  SecKeychainRef keychain;
  err = SecKeychainCopyDefault(&keychain);
  if (err) {
    crypto::LogCSSMError("SecKeychainCopyDefault", err);
    return err;
  }
  base::mac::ScopedCFTypeRef<SecKeychainRef> scoped_keychain(keychain);
  {
    base::AutoLock locked(crypto::GetMacSecurityServicesLock());
    err = SecKeyCreatePair(
        keychain,
        CSSM_ALGID_RSA,
        size_in_bits,
        0LL,
        // public key usage and attributes:
        CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_WRAP,
        CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT,
        // private key usage and attributes:
        CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_SIGN | CSSM_KEYUSE_UNWRAP,
        CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT |
            CSSM_KEYATTR_SENSITIVE,
        initial_access,
        out_pub_key, out_priv_key);
  }
  if (err)
    crypto::LogCSSMError("SecKeyCreatePair", err);
  return err;
}

static OSStatus CreateSignatureContext(SecKeyRef key,
                                       CSSM_ALGORITHMS algorithm,
                                       CSSM_CC_HANDLE* out_cc_handle) {
  OSStatus err;
  const CSSM_ACCESS_CREDENTIALS* credentials = NULL;
  {
    base::AutoLock locked(crypto::GetMacSecurityServicesLock());
    err = SecKeyGetCredentials(key,
                               CSSM_ACL_AUTHORIZATION_SIGN,
                               kSecCredentialTypeDefault,
                               &credentials);
  }
  if (err) {
    crypto::LogCSSMError("SecKeyGetCredentials", err);
    return err;
  }

  CSSM_CSP_HANDLE csp_handle = 0;
  {
    base::AutoLock locked(crypto::GetMacSecurityServicesLock());
    err = SecKeyGetCSPHandle(key, &csp_handle);
  }
  if (err) {
    crypto::LogCSSMError("SecKeyGetCSPHandle", err);
    return err;
  }

  const CSSM_KEY* cssm_key = NULL;
  {
    base::AutoLock locked(crypto::GetMacSecurityServicesLock());
    err = SecKeyGetCSSMKey(key, &cssm_key);
  }
  if (err) {
    crypto::LogCSSMError("SecKeyGetCSSMKey", err);
    return err;
  }

  err = CSSM_CSP_CreateSignatureContext(csp_handle,
                                        algorithm,
                                        credentials,
                                        cssm_key,
                                        out_cc_handle);
  if (err)
    crypto::LogCSSMError("CSSM_CSP_CreateSignatureContext", err);
  return err;
}

static OSStatus SignData(CSSM_DATA data,
                         SecKeyRef private_key,
                         CSSM_DATA* signature) {
  CSSM_CC_HANDLE cc_handle;
  OSStatus err = CreateSignatureContext(private_key,
                                        CSSM_ALGID_MD5WithRSA,
                                        &cc_handle);
  if (err) {
    crypto::LogCSSMError("CreateSignatureContext", err);
    return err;
  }
  err = CSSM_SignData(cc_handle, &data, 1, CSSM_ALGID_NONE, signature);
  if (err)
    crypto::LogCSSMError("CSSM_SignData", err);
  CSSM_DeleteContext(cc_handle);
  return err;
}

}  // namespace net
