/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*
 * XSEC
 *
 * WinCAPICryptoKeyRSA := Windows implementation of RSA Keys
 *
 * Author(s): Berin Lautenbach
 *
 * $Id$
 *
 */

#ifndef WINCAPICRYPTOKEYRSA_INCLUDE
#define WINCAPICRYPTOKEYRSA_INCLUDE

#include <xsec/enc/XSECCryptoKeyRSA.hpp>

#if defined (XSEC_HAVE_WINCAPI)

#if !defined(_WIN32_WINNT)
#    define _WIN32_WINNT 0x0400
#endif

#include <wincrypt.h>

class WinCAPICryptoProvider;

/**
 * \ingroup wincapicrypto
 */

/**
 * \brief WinCAPI implementation of the interface class for RSA keys.
 *
 * The library uses classes derived from this to process RSA keys.
 */

class XSEC_EXPORT WinCAPICryptoKeyRSA : public XSECCryptoKeyRSA {

public :

    /** @name Constructors and Destructors */
    //@{

    /**
     * \brief Create an RSA key
     *
     * Constructor used to create an "empty" RSA key, that the
     * library will later set parameters for the public key within.
     *
     * @param prov A handle to a PROV_RSA_FULL provider that the
     * library will eventually import the key into
     */

    WinCAPICryptoKeyRSA(HCRYPTPROV prov);

    /**
     * \brief Dedicated WinCAPI constructor for a public RSA key
     *
     * Create a public RSA key for use in XSEC from an existing HCRYPTKEY
     *
     * @param prov The handle to the provider that was used to create the key
     * @param k The key to use
     * @note k is owned by the library.  When the wrapper
     * WinCAPICryptoKeyRSA is deleted, k will be destroyed using
     * CryptDestroyKey()
     */

    WinCAPICryptoKeyRSA(HCRYPTPROV prov, HCRYPTKEY k);

    /**
     * \brief Dedicated WinCAPI constructor for a private RSA key
     *
     * Create a public RSA key for use in XSEC from an keySpec
     *
     * @param prov The handle to the provider that was used to create the key
     * @param keySpec The key to use (AT_SIGNATURE or AT_KEYEXCHANGE
     * @param isPrivate Should be true.  May be used later for public
     * keys created this way
     */

    WinCAPICryptoKeyRSA(HCRYPTPROV prov, DWORD keySpec, bool isPrivate);

    virtual ~WinCAPICryptoKeyRSA();

    //@}

    /** @name Key Interface methods */
    //@{

    /**
     * \brief Return the type of this key.
     *
     * For RSA keys, this allows people to determine whether this is a
     * public key, private key or a key pair
     */

    virtual XSECCryptoKey::KeyType getKeyType() const;

    /**
     * \brief Return the WinCAPI identifier string
     */

    virtual const XMLCh* getProviderName() const;

    /**
     * \brief Replicate key
     */

    virtual XSECCryptoKey* clone() const;

    //@}

    /** @name Mandatory RSA interface methods
     *
     * These classes are required by the library.
     */
    //@{

    /**
     * \brief Set the OAEPparams string
     *
     * By default, the library expects crypto implementations to perform
     * OAEP padding with no params.  This call allows the library (or user)
     * to set a params value prior to an encrypt/decrypt operation.
     *
     * @param params buffer containing the params data.  Pass in NULL to clear any
     * old paramters.
     * @param paramsLen number of bytes in buffer to use.  Pass in 0 to clear any
     * old parameters.
     * @note The Microsoft Crypto RSA_AES and RSA_FULL providers do not support
     * the ability to set OAEP parameters, so this will throw an
     * XSECCryptoException::UnsupportedError, unless the passed in paramters
     * are NULL and 0 (to clear).
     */

    virtual void setOAEPparams(unsigned char* params, unsigned int paramsLen);

    /**
     * \brief Get OAEPparams Length
     *
     * @returns the number of bytes of the OAEPparams buffer (assuming it has been set)
     * @note The Microsoft Crypto RSA_AES and RSA_FULL providers do not support
     * the ability to set OAEP parameters, so this will always return 0
     */

    virtual unsigned int getOAEPparamsLen() const;

    /**
     * \brief Get the OAEPparams
     *
     * @returns a pointer to the (crypto object owned) buffer holding the OAEPparams
     * or NULL if no params are held
     * @note The Microsoft Crypto RSA_AES and RSA_FULL providers do not support
     * the ability to set OAEP parameters, so this will always return NULL
     */

    virtual const unsigned char* getOAEPparams() const;

    /**
     * \brief Set the MGF
     *
     * By default, the library expects crypto implementations to perform
     * OAEP padding with MGF_SHA1.  This call allows the library (or user)
     * to set a different choice.
     *
     * @param mgf the MGF constant identifying the function to use
     */

    virtual void setMGF(maskGenerationFunc mgf);

    /**
     * \brief Get the MGF
     *
     * @returns the MGF constant in use
     */

    virtual enum maskGenerationFunc getMGF(void) const;

    /**
     * \brief Verify a SHA1 PKCS1 encoded signature
     *
     * The library will call this function to validate an RSA signature
     * The standard by default uses SHA1 in a PKCS1 encoding.
     *
     * @param hashBuf Buffer containing the pre-calculated (binary) digest
     * @param hashLen Length of the data in the digest buffer
     * @param base64Signature Buffer containing the Base64 encoded signature
     * @param sigLen Length of the data in the signature buffer
     * @param type The hash method that was used to create the hash that is being
     * passed in
     * @returns true if the signature was valid, false otherwise
     */

    virtual bool verifySHA1PKCS1Base64Signature(const unsigned char* hashBuf,
                                 unsigned int hashLen,
                                 const char* base64Signature,
                                 unsigned int sigLen,
								 XSECCryptoHash::HashType type) const;

    /**
     * \brief Create a signature
     *
     * The library will call this function to create a signature from
     * a pre-calculated digest.  The output signature will
     * be Base64 encoded such that it can be placed directly into the
     * XML document
     *
     * @param hashBuf Buffer containing the pre-calculated (binary) digest
     * @param hashLen Number of bytes of hash in the hashBuf
     * @param base64SignatureBuf Buffer to place the base64 encoded result
     * in.
     * @param base64SignatureBufLen Implementations need to ensure they do
     * not write more bytes than this into the buffer
     * @param type The hash method that was used to create the hash that is being
     * passed in
     */

    virtual unsigned int signSHA1PKCS1Base64Signature(unsigned char * hashBuf,
                                unsigned int hashLen,
                                char * base64SignatureBuf,
                                unsigned int base64SignatureBufLen,
								XSECCryptoHash::HashType type) const;

    /**
     * \brief Decrypt using private key
     *
     * The library will call this function to decrypt a piece of cipher
     * text using the private component of this key.
     *
     * @param inBuf cipher text to decrypt
     * @param plainBuf output buffer for decrypted bytes
     * @param inLength bytes of cipher text to decrypt
     * @param maxOutLength size of outputBuffer
     * @param padding Type of padding (PKCS 1.5 or OAEP)
     * @param type Hash Method for OAEP encryption (OAEPParams should be
     * set using setOAEPparams()
     */

    virtual unsigned int privateDecrypt(const unsigned char* inBuf,
                                 unsigned char* plainBuf,
                                 unsigned int inLength,
                                 unsigned int maxOutLength,
                                 PaddingType padding,
								 XSECCryptoHash::HashType type) const;

    /**
     * \brief Encrypt using a public key
     *
     * The library will call this function to encrypt a plain text buffer
     * using the public component of this key.
     *
     * @param inBuf plain text to decrypt
     * @param cipherBuf output buffer for decrypted bytes
     * @param inLength bytes of plain text to encrypt
     * @param maxOutLength size of outputBuffer
     * @param padding Type of padding (PKCS 1.5 or OAEP)
     * @param type Hash Method for OAEP encryption (OAEPParams should be
     * set using setOAEPparams()
     */

    virtual unsigned int publicEncrypt(const unsigned char* inBuf,
                                 unsigned char* cipherBuf,
                                 unsigned int inLength,
                                 unsigned int maxOutLength,
                                 PaddingType padding,
								 XSECCryptoHash::HashType type) const;

    /**
     * \brief Obtain the length of an RSA key
     *
     * @returns The length of the rsa key (in bytes)
     */

    virtual unsigned int getLength() const;

    //@}

    /** @name Optional Interface methods
     *
     * Have been implemented to allow interoperability testing
     */

    //@{

    /**
     * \brief Load the modulus
     *
     * Load the modulus from a Base64 encoded string
     *
     * param b64 A buffer containing the encoded string
     * param len The length of the data in the buffer
     */

    virtual void loadPublicModulusBase64BigNums(const char* b64, unsigned int len);

    /**
     * \brief Load the exponent
     *
     * Load the exponent from a Base64 encoded string
     *
     * param b64 A buffer containing the encoded string
     * param len The length of the data in the buffer
     */

    virtual void loadPublicExponentBase64BigNums(const char* b64, unsigned int len);

    //@}

    /** @name WinCAPI Specific Functions */
    //@{


    /**
     * \brief Retrieve the exponent
     *
     * Retrieves the exponent in ds:CryptoBinary encoded format
     *
     * @param b64 Buffer to place encoded exponent into
     * @param len Maximum number of bytes to place in buffer
     * @returns The number of bytes placed in the buffer
     */

    unsigned int getExponentBase64BigNums(char* b64, unsigned int len);

    /**
     * \brief Retrieve the modulus
     *
     * Retrieves the modulus in ds:CryptoBinary encoded format
     *
     * @param b64 Buffer to place the encoded modulus into
     * @param len Maximum number of bytes to place in buffer
     * @returns The number of bytes placed in the buffer
     */

    unsigned int getModulusBase64BigNums(char* b64, unsigned int len);

    /**
     * \brief Import key and return it
     *
     * Retrieves the RSA key as HCRYPTKEY
     *
     * @returns The key
     */

    HCRYPTKEY importKey() const;

    //@}

private:
    HCRYPTPROV m_p;
    mutable HCRYPTKEY m_key;    // For a public key
    DWORD m_keySpec;        	// For a private key

    BYTE* mp_modulus;
    BYTE* mp_exponent;

    unsigned int m_modulusLen;
    unsigned int m_exponentLen;

    // Instruct to import from parameters
    void loadParamsFromKey();

};

#endif /* XSEC_HAVE_WINCAPI */
#endif /* WINCAPICRYPTOKEYRSA_INCLUDE */
