blautenb    2003/04/11 05:24:06

  Added:       c/src/enc/WinCAPI WinCAPICryptoKeyRSA.hpp
                        WinCAPICryptoKeyRSA.cpp
  Log:
  Full implementation of WinCAPI
  
  Revision  Changes    Path
  1.1                  xml-security/c/src/enc/WinCAPI/WinCAPICryptoKeyRSA.hpp
  
  Index: WinCAPICryptoKeyRSA.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "<WebSig>" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2001, Institute for
   * Data Communications Systems, <http://www.nue.et-inf.uni-siegen.de/>.
   * The development of this software was partly funded by the European 
   * Commission in the <WebSig> project in the ISIS Programme. 
   * For more information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * XSEC
   *
   * WinCAPICryptoKeyRSA := Windows implementation of RSA Keys
   *
   * Author(s): Berin Lautenbach
   *
   * $Id: WinCAPICryptoKeyRSA.hpp,v 1.1 2003/04/11 12:24:06 blautenb Exp $
   *
   */
  
  #ifndef WINCAPICRYPTOKEYRSA_INCLUDE
  #define WINCAPICRYPTOKEYRSA_INCLUDE
  
  #include <xsec/enc/XSECCryptoKeyRSA.hpp>
  
  #if !defined(_WIN32_WINNT)
  #     define _WIN32_WINNT 0x0400
  #endif
  
  #include <wincrypt.h>
  
  class WinCAPICryptoProvider;
  
  class DSIG_EXPORT WinCAPICryptoKeyRSA : public XSECCryptoKeyRSA {
  
  public :
  
        // Constructors/Destructors
        
        WinCAPICryptoKeyRSA(WinCAPICryptoProvider * owner);
  
        /**
         * \brief Dedicated WinCAPI constructor
         *
         * Create a RSA key for use in XSEC from an existing HCRYPTKEY
         *
         * @param owner The owner provider object (needed to find CSP)
         * @param k The key to use
         * @param havePrivate The CSP holds the private key as well as public
         * @note k is owned by the library.  When the wrapper 
         * WinCAPICryptoKeyRSA is deleted, k will be destroyed using
         * CryptDestroyKey()
         */
  
        WinCAPICryptoKeyRSA(WinCAPICryptoProvider * owner, HCRYPTKEY k, bool 
havePrivate = false);
  
        virtual ~WinCAPICryptoKeyRSA();
  
        // Generic key functions
  
        virtual XSECCryptoKey::KeyType getKeyType();
        virtual const XMLCh * getProviderName() {return 
DSIGConstants::s_unicodeStrPROVWinCAPI;}
        virtual XSECCryptoKey * clone();
  
        // RSA Specific Functions
  
        virtual void loadPublicModulusBase64BigNums(const char * b64, unsigned 
int len);
        virtual void loadPublicExponentBase64BigNums(const char * b64, unsigned 
int len);
  
        // Signature functions
  
        virtual bool verifySHA1PKCS1Base64Signature(const unsigned char * 
hashBuf, 
                                                                 unsigned int 
hashLen,
                                                                 const char * 
base64Signature,
                                                                 unsigned int 
sigLen);
  
        virtual unsigned int signSHA1PKCS1Base64Signature(unsigned char * 
hashBuf,
                unsigned int hashLen,
                char * base64SignatureBuf,
                unsigned int base64SignatureBufLen);
  
        // "Extra" WinCAPI functions
  
        WinCAPICryptoKeyRSA(HCRYPTKEY k);
  
        // Some useful functions for extracting parameters from a Windows key
  
        unsigned int getExponentBase64BigNums(char * b64, unsigned int len);
        unsigned int getModulusBase64BigNums(char * b64, unsigned int len);
  
  private:
  
        HCRYPTKEY                                       m_key;  
        WinCAPICryptoProvider           * mp_ownerProvider;
        bool                                            m_havePrivate;          
// Do we have the private key?
  
        BYTE                                            * mp_modulus;
        BYTE                                            * mp_exponent;
  
        unsigned int                            m_modulusLen;
        unsigned int                            m_exponentLen;
  
        // Instruct to import from parameters
  
        void importKey(void);
        void loadParamsFromKey(void);
  
  };
  
  #endif /* WINCAPICRYPTOKEYRSA_INCLUDE */
  
  
  
  1.1                  xml-security/c/src/enc/WinCAPI/WinCAPICryptoKeyRSA.cpp
  
  Index: WinCAPICryptoKeyRSA.cpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "<WebSig>" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2001, Institute for
   * Data Communications Systems, <http://www.nue.et-inf.uni-siegen.de/>.
   * The development of this software was partly funded by the European 
   * Commission in the <WebSig> project in the ISIS Programme. 
   * For more information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * XSEC
   *
   * WinCAPICryptoKeyRSA := RSA Keys
   *
   * Author(s): Berin Lautenbach
   *
   * $Id: WinCAPICryptoKeyRSA.cpp,v 1.1 2003/04/11 12:24:06 blautenb Exp $
   *
   */
  
  #include <xsec/enc/WinCAPI/WinCAPICryptoProvider.hpp>
  #include <xsec/enc/WinCAPI/WinCAPICryptoKeyRSA.hpp>
  #include <xsec/enc/XSCrypt/XSCryptCryptoBase64.hpp>
  #include <xsec/enc/XSECCryptoException.hpp>
  #include <xsec/framework/XSECError.hpp>
  
  #include <xercesc/util/Janitor.hpp>
  
  XSEC_USING_XERCES(ArrayJanitor);
  
  
  WinCAPICryptoKeyRSA::WinCAPICryptoKeyRSA(WinCAPICryptoProvider * owner) {
  
        // Create a new key to be loaded as we go
  
        m_key = 0;
        mp_ownerProvider = owner;
        m_havePrivate = false;
  
        mp_exponent = NULL;
        m_exponentLen = 0;
        mp_modulus = NULL;
        m_modulusLen = 0;
  
  };
  
  WinCAPICryptoKeyRSA::~WinCAPICryptoKeyRSA() {
  
  
        // If we have a RSA, delete it
  
        if (m_key == 0)
                CryptDestroyKey(m_key);
  
        if (mp_exponent)
                delete[] mp_exponent;
        if (mp_modulus)
                delete[] mp_modulus;
  
  };
  
  WinCAPICryptoKeyRSA::WinCAPICryptoKeyRSA(WinCAPICryptoProvider * owner, 
                                                                                
 HCRYPTKEY k,
                                                                                
 bool havePrivate) :
  mp_ownerProvider(owner),
  m_havePrivate(havePrivate) {
  
        mp_ownerProvider = owner;
        m_key = k;              // NOTE - We OWN this handle
  
        mp_exponent = mp_modulus = NULL;
        m_exponentLen = m_modulusLen = 0;
  
  }
  
  
  // Generic key functions
  
  XSECCryptoKey::KeyType WinCAPICryptoKeyRSA::getKeyType() {
  
        // Find out what we have
        if (m_key == 0) {
  
                if (mp_exponent == NULL ||
                        mp_modulus == NULL)
                        return KEY_NONE;
                else
                        return KEY_RSA_PUBLIC;
  
        }
  
        if (m_havePrivate == true)
                return KEY_RSA_PAIR;
  
        return KEY_RSA_PUBLIC;
  
  }
  
  // 
--------------------------------------------------------------------------------
  //           Load key from parameters
  // 
--------------------------------------------------------------------------------
  
  void WinCAPICryptoKeyRSA::loadPublicModulusBase64BigNums(const char * b64, 
unsigned int len) {
  
        if (mp_modulus != NULL) {
                delete[] mp_modulus;
                mp_modulus = NULL;              // In case we get an exception
        }
  
        mp_modulus = WinCAPICryptoProvider::b642WinBN(b64, len, m_modulusLen);
  
  }
  
  void WinCAPICryptoKeyRSA::loadPublicExponentBase64BigNums(const char * b64, 
unsigned int len) {
  
        if (mp_exponent != NULL) {
                delete[] mp_exponent;
                mp_exponent = NULL;             // In case we get an exception
        }
  
        mp_exponent = WinCAPICryptoProvider::b642WinBN(b64, len, m_exponentLen);
  
  }
  
  void WinCAPICryptoKeyRSA::importKey(void) {
        
        if (m_key != 0 ||
                mp_exponent == NULL ||
                mp_modulus == NULL)
  
                return;
  
  
        // Create a RSA Public-Key blob
  
        // First build a buffer to hold everything
  
        BYTE * blobBuffer;
        unsigned int blobBufferLen = WINCAPI_BLOBHEADERLEN + 
WINCAPI_RSAPUBKEYLEN + m_modulusLen;
        XSECnew(blobBuffer, BYTE[blobBufferLen]);
        ArrayJanitor<BYTE> j_blobBuffer(blobBuffer);
  
        // Blob header
        BLOBHEADER * header = (BLOBHEADER *) blobBuffer;
  
        header->bType = PUBLICKEYBLOB;
        header->bVersion = 0x02;                        // We are using a 
version 2 blob
        header->reserved = 0;
        header->aiKeyAlg = CALG_RSA_SIGN;
  
        // Now the public key header
        RSAPUBKEY * pubkey = (RSAPUBKEY *) (blobBuffer + WINCAPI_BLOBHEADERLEN);
  
        pubkey->magic = 0x31415352;                     // ASCII encoding of 
RSA1
        pubkey->bitlen = m_modulusLen * 8;              // Number of bits in 
prime modulus
        pubkey->pubexp = 0;
        BYTE * i = ((BYTE *) &(pubkey->pubexp));
        for (unsigned int j = 0; j < m_exponentLen; ++j)
                *i++ = mp_exponent[j];
  
        // Now copy in the modulus
        i = (BYTE *) (pubkey);
        i += WINCAPI_RSAPUBKEYLEN;
  
        memcpy(i, mp_modulus, m_modulusLen);
  
        // Now that we have the blob, import
        BOOL fResult = CryptImportKey(
                                        mp_ownerProvider->getProviderRSA(),
                                        blobBuffer,
                                        blobBufferLen,
                                        0,                              // Not 
signed
                                        0,                              // No 
flags
                                        &m_key);
  
        if (fResult == 0) {
                
                throw XSECCryptoException(XSECCryptoException::RSAError,
                        "WinCAPI:RSA Error attempting to import key 
parameters");
  
        }
  
  }
  
  
  // 
--------------------------------------------------------------------------------
  //           Verify a signature encoded as a Base64 string
  // 
--------------------------------------------------------------------------------
  
  bool WinCAPICryptoKeyRSA::verifySHA1PKCS1Base64Signature(const unsigned char 
* hashBuf, 
                                                                 unsigned int 
hashLen,
                                                                 const char * 
base64Signature,
                                                                 unsigned int 
sigLen) {
  
        // Use the currently loaded key to validate the Base64 encoded signature
  
        if (m_key == 0) {
  
                // Try to import from the parameters
                importKey();
  
                if (m_key == 0) {
                        throw XSECCryptoException(XSECCryptoException::RSAError,
                                "WinCAPI:RSA - Attempt to validate signature 
with empty key");
                }
        }
  
        // Decode the signature
        unsigned char * rawSig;
        DWORD rawSigLen;
        XSECnew(rawSig, BYTE [sigLen]);
        ArrayJanitor<BYTE> j_rawSig(rawSig);
  
        // Decode the signature
        XSCryptCryptoBase64 b64;
  
        b64.decodeInit();
        rawSigLen = b64.decode((unsigned char *) base64Signature, sigLen, 
rawSig, sigLen);
        rawSigLen += b64.decodeFinish(&rawSig[rawSigLen], sigLen - rawSigLen);
        
        BYTE * rawSigFinal;
        XSECnew(rawSigFinal, BYTE[rawSigLen]);
        ArrayJanitor<BYTE> j_rawSigFinal(rawSigFinal);
  
        BYTE * j, *l;
        j = rawSig;
        l = rawSigFinal + rawSigLen - 1;
        
        while (l >= rawSigFinal) {
                *l-- = *j++;
        }
  
        // Have to create a Windows hash object and feed in the hash
        BOOL fResult;
        HCRYPTHASH h;
        fResult = CryptCreateHash(mp_ownerProvider->getProviderRSA(), 
                                        CALG_SHA1, 
                                        0, 
                                        0,
                                        &h);
  
        if (!fResult) {
                throw XSECCryptoException(XSECCryptoException::RSAError,
                        "WinCAPI:RSA - Error creating Windows Hash Object");
        }
  
        // Feed the hash value into the newly created hash object
        fResult = CryptSetHashParam(
                                        h, 
                                        HP_HASHVAL,
                                        (unsigned char *) hashBuf,
                                        0);
  
        if (!fResult) {
                throw XSECCryptoException(XSECCryptoException::RSAError,
                        "WinCAPI:RSA - Error Setting Hash Value in Windows Hash 
object");
        }
  
        // Now validate
        fResult = CryptVerifySignature(
                                h,
                                rawSigFinal,
                                rawSigLen,
                                m_key,
                                NULL,
                                0);
  
        if (!fResult) {
  
                DWORD error = GetLastError();
  
                if (error != NTE_BAD_SIGNATURE) {
                        throw XSECCryptoException(XSECCryptoException::RSAError,
                        "WinCAPI:RSA - Error occurred in RSA validation");
                }
  
                return false;
        }
  
        return true;
  
  }
  
  // 
--------------------------------------------------------------------------------
  //           Sign and encode result as a Base64 string
  // 
--------------------------------------------------------------------------------
  
  
  unsigned int WinCAPICryptoKeyRSA::signSHA1PKCS1Base64Signature(unsigned char 
* hashBuf,
                unsigned int hashLen,
                char * base64SignatureBuf,
                unsigned int base64SignatureBufLen) {
  
        // Sign a pre-calculated hash using this key
  
        if (m_key == NULL) {
  
                throw XSECCryptoException(XSECCryptoException::RSAError,
                        "WinCAPI:RSA - Attempt to sign data with empty key");
        }
  
        if (m_havePrivate == false) {
  
                throw XSECCryptoException(XSECCryptoException::RSAError,
                        "WinCAPI:RSA - Attempt to sign data a public key");
        }
  
        // Have to create a Windows hash object and feed in the hash
        BOOL fResult;
        HCRYPTHASH h;
        fResult = CryptCreateHash(mp_ownerProvider->getProviderRSA(), 
                                        CALG_SHA1, 
                                        0, 
                                        0,
                                        &h);
  
        if (!fResult) {
                throw XSECCryptoException(XSECCryptoException::RSAError,
                        "WinCAPI:RSA - Error creating Windows Hash Object");
        }
  
        // Feed the hash value into the newly created hash object
        fResult = CryptSetHashParam(
                                        h, 
                                        HP_HASHVAL, 
                                        hashBuf, 
                                        0);
  
        if (!fResult) {
                throw XSECCryptoException(XSECCryptoException::RSAError,
                        "WinCAPI:RSA - Error Setting Hash Value in Windows Hash 
object");
        }
  
        // Now sign
        DWORD rawSigLen;
        fResult = CryptSignHash(
                                h,
                                AT_SIGNATURE,
                                NULL,
                                0,
                                NULL,
                                &rawSigLen);
  
        if (!fResult || rawSigLen < 1) {
  
                throw XSECCryptoException(XSECCryptoException::RSAError,
                "WinCAPI:RSA - Error occurred obtaining RSA sig length");
        }
  
        BYTE * rawSig;
        XSECnew(rawSig, BYTE[rawSigLen]);
        ArrayJanitor<BYTE> j_rawSig(rawSig);
  
        fResult = CryptSignHash(
                                h,
                                AT_SIGNATURE,
                                NULL,
                                0,
                                rawSig,
                                &rawSigLen);
  
        if (!fResult || rawSigLen < 1) {
  
                throw XSECCryptoException(XSECCryptoException::RSAError,
                "WinCAPI:RSA - Error occurred signing hash");
        }
  
        // Now encode into a signature block
        BYTE *rawSigFinal;
        XSECnew(rawSigFinal, BYTE[rawSigLen]);
        ArrayJanitor<BYTE> j_rawSigFinal(rawSigFinal);
  
        BYTE * i, * j;
  
        i = rawSig;
        j = rawSigFinal + rawSigLen - 1;
  
        while (j >= rawSigFinal) {
                *j-- = *i++;
        }
  
        // Now encode
        XSCryptCryptoBase64 b64;
        b64.encodeInit();
        unsigned int ret = b64.encode(rawSigFinal, rawSigLen, (unsigned char *) 
base64SignatureBuf, base64SignatureBufLen);
        ret += b64.encodeFinish((unsigned char *) &base64SignatureBuf[ret], 
base64SignatureBufLen - ret);
  
        return ret;
  
  }
  
  XSECCryptoKey * WinCAPICryptoKeyRSA::clone() {
  
        WinCAPICryptoKeyRSA * ret;
  
        XSECnew(ret, WinCAPICryptoKeyRSA(mp_ownerProvider));
        
        if (m_key != 0) {
  
                // CryptDuplicateKey is not supported in Windows NT, so we need 
to export and then
                // reimport the key to get a copy
  
                BYTE keyBuf[2048];
                DWORD keyBufLen = 2048;
                CryptExportKey(m_key, 0, PUBLICKEYBLOB, 0, keyBuf, &keyBufLen);
  
                // Now re-import
                CryptImportKey(mp_ownerProvider->getProviderRSA(), keyBuf, 
keyBufLen, NULL, 0, &ret->m_key);
        }
  
        ret->m_exponentLen = m_exponentLen;
        if (mp_exponent != NULL) {
                XSECnew(ret->mp_exponent, BYTE[m_exponentLen]);
                memcpy(ret->mp_exponent, mp_exponent, m_exponentLen);
        }
        else
                ret->mp_exponent = NULL;
  
        ret->m_modulusLen = m_modulusLen;
        if (mp_modulus != NULL) {
                XSECnew(ret->mp_modulus, BYTE[m_modulusLen]);
                memcpy(ret->mp_modulus, mp_modulus, m_modulusLen);
        }
        else
                ret->mp_modulus = NULL;
  
        return ret;
  
  }
  // 
--------------------------------------------------------------------------------
  //           Some utility functions
  // 
--------------------------------------------------------------------------------
  
  void WinCAPICryptoKeyRSA::loadParamsFromKey(void) {
  
        if (m_key == 0)
                return;
  
        // Export key into a keyblob
        BOOL fResult;
        DWORD blobLen;
  
        fResult = CryptExportKey(
                m_key,
                0,
                PUBLICKEYBLOB,
                0,
                NULL,
                &blobLen);
        
        if (fResult == 0 || blobLen < 1) {
                throw XSECCryptoException(XSECCryptoException::RSAError,
                        "WinCAPI:RSA - Error exporting public key");
        }
  
        BYTE * blob;
        XSECnew(blob, BYTE[blobLen]);
        ArrayJanitor<BYTE> j_blob(blob);
  
        fResult = CryptExportKey(
                m_key,
                0,
                PUBLICKEYBLOB,
                0,
                blob,
                &blobLen);
        
        if (fResult == 0 || blobLen < 1) {
                throw XSECCryptoException(XSECCryptoException::RSAError,
                        "WinCAPI:RSA - Error exporting public key");
        }
  
        RSAPUBKEY * pk = (RSAPUBKEY *) ( blob + WINCAPI_BLOBHEADERLEN );
        DWORD keyLen = pk->bitlen / 8;
  
        // Copy the keys
        
        BYTE * i = (BYTE *) ( pk );
        i += WINCAPI_RSAPUBKEYLEN;
        if (mp_modulus != NULL)
                delete[] mp_modulus;
  
        m_modulusLen = keyLen;
        XSECnew(mp_modulus, BYTE[m_modulusLen]);
        memcpy(mp_modulus, i, m_modulusLen);
  
        // Take the simple way out
        XSECnew(mp_exponent, BYTE[4]);
        *((DWORD *) mp_exponent) = pk->pubexp;
  
        // Now cut any leading 0s (Windows is LE, so start least significant 
end)
  
        m_exponentLen = 3;
        while (m_exponentLen > 0 && mp_exponent[m_exponentLen] == 0)
                m_exponentLen--;
  
        m_exponentLen++;        // Make it a length as apposed to an offset
  }
  
  unsigned int WinCAPICryptoKeyRSA::getExponentBase64BigNums(char * b64, 
unsigned int len) {
  
        if (m_key == 0 && mp_exponent == NULL) {
  
                return 0;       // Nothing we can do
  
        }
  
        if (mp_exponent == NULL) {
  
                loadParamsFromKey();
  
        }
  
        unsigned int bLen;
        unsigned char * b =  WinCAPICryptoProvider::WinBN2b64(mp_exponent, 
m_exponentLen, bLen);
        if (bLen > len)
                bLen = len;
        memcpy(b64, b, bLen);
        delete[] b;
  
        return bLen;
  
  }
  
  unsigned int WinCAPICryptoKeyRSA::getModulusBase64BigNums(char * b64, 
unsigned int len) {
  
        if (m_key == 0 && mp_modulus == NULL) {
  
                return 0;       // Nothing we can do
  
        }
  
        if (mp_modulus == NULL) {
  
                loadParamsFromKey();
  
        }
  
        unsigned int bLen;
        unsigned char * b =  WinCAPICryptoProvider::WinBN2b64(mp_modulus, 
m_modulusLen, bLen);
        if (bLen > len)
                bLen = len;
        memcpy(b64, b, bLen);
        delete[] b;
  
        return bLen;
  
  }
  
  
  

Reply via email to