blautenb    2003/08/31 05:48:50

  Modified:    c/src/enc XSECCryptoException.cpp XSECCryptoException.hpp
                        XSECCryptoKey.hpp XSECCryptoProvider.hpp
               c/src/enc/OpenSSL OpenSSLCryptoProvider.cpp
                        OpenSSLCryptoProvider.hpp
  Added:       c/src/enc XSECCryptoSymmetricKey.hpp
               c/src/enc/OpenSSL OpenSSLCryptoSymmetricKey.cpp
                        OpenSSLCryptoSymmetricKey.hpp
  Log:
  First cut at block-cipher interface
  
  Revision  Changes    Path
  1.6       +3 -2      xml-security/c/src/enc/XSECCryptoException.cpp
  
  Index: XSECCryptoException.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/XSECCryptoException.cpp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- XSECCryptoException.cpp   5 Jul 2003 10:30:32 -0000       1.5
  +++ XSECCryptoException.cpp   31 Aug 2003 12:48:50 -0000      1.6
  @@ -82,7 +82,8 @@
        "Memory allocation error",
        "X509 Error",
        "DSA Error",
  -     "RSA Error"
  +     "RSA Error",
  +     "Symmetric Error"
   
   };
   
  
  
  
  1.7       +3 -2      xml-security/c/src/enc/XSECCryptoException.hpp
  
  Index: XSECCryptoException.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/XSECCryptoException.hpp,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- XSECCryptoException.hpp   5 Jul 2003 10:30:32 -0000       1.6
  +++ XSECCryptoException.hpp   31 Aug 2003 12:48:50 -0000      1.7
  @@ -128,7 +128,8 @@
                X509Error                                       = 5,            
// X509 problem
                DSAError                                        = 6,            
// DSA Error
                RSAError                                        = 7,            
// RSA Error
  -             UnknownError                            = 8                     
// Must be last!
  +             SymmetricError                          = 8,
  +             UnknownError                            = 9                     
// Must be last!
   
        };
   
  
  
  
  1.9       +3 -2      xml-security/c/src/enc/XSECCryptoKey.hpp
  
  Index: XSECCryptoKey.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/XSECCryptoKey.hpp,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- XSECCryptoKey.hpp 5 Jul 2003 10:30:32 -0000       1.8
  +++ XSECCryptoKey.hpp 31 Aug 2003 12:48:50 -0000      1.9
  @@ -113,7 +113,8 @@
                KEY_RSA_PUBLIC,
                KEY_RSA_PRIVATE,
                KEY_RSA_PAIR,
  -             KEY_HMAC
  +             KEY_HMAC,
  +             KEY_SYMMETRIC
        
        };
   
  
  
  
  1.10      +14 -28    xml-security/c/src/enc/XSECCryptoProvider.hpp
  
  Index: XSECCryptoProvider.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/XSECCryptoProvider.hpp,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- XSECCryptoProvider.hpp    5 Jul 2003 10:30:32 -0000       1.9
  +++ XSECCryptoProvider.hpp    31 Aug 2003 12:48:50 -0000      1.10
  @@ -77,6 +77,7 @@
   #include <xsec/enc/XSECCryptoX509.hpp>
   #include <xsec/enc/XSECCryptoKeyDSA.hpp>
   #include <xsec/enc/XSECCryptoKeyRSA.hpp>
  +#include <xsec/enc/XSECCryptoSymmetricKey.hpp>
   
   /**
    * @defgroup crypto Cryptographic Abstraction Layer
  @@ -179,33 +180,6 @@
   
   public :
   
  -     /**
  -      * Enumeration of types of keys that must be handled by
  -      * the CryptoProvider
  -      */
  -
  -     enum CryptoKeyType {
  -
  -             KEY_NONE                        = 0,        /**< Key is empty - 
type unknown */
  -             KEY_DSA_PUB                     = 1,            /**< DSA key - 
Public part only */
  -             KEY_DSA_PRIV            = 2,            /**< DSA key - Private 
part only */
  -             KEY_DSA_PAIR            = 3             /**< DSA key - Full Key 
Pair */
  -
  -     };
  -
  -     /**
  -      * Enumeration of cryptographic algorithms that the provider must
  -      * supply
  -      */
  -
  -     enum CryptoAlgorithmType {
  -
  -             ALG_NONE                        = 0,       /**< Used for 
catching errors */
  -             ALG_DSA                         = 1        /**< Digital 
Signature Algorithm */
  -
  -     };
  -
  -
        /** @name Constructors and Destructors */
        //@{
        
  @@ -326,6 +300,18 @@
         */
   
        virtual XSECCryptoX509                  * X509() = 0;
  +
  +     /**
  +      * \brief Return a Symmetric Key implementation object.
  +      *
  +      * Call used by the library to obtain a bulk encryption
  +      * object.
  +      *
  +      * @returns Pointer to the new SymmetricKey object
  +      * @see XSECCryptoSymmetricKey
  +      */
  +
  +     virtual XSECCryptoSymmetricKey  * 
keySymmetric(XSECCryptoSymmetricKey::SymmetricKeyType alg) = 0;
   
        //@}
   
  
  
  
  1.1                  xml-security/c/src/enc/XSECCryptoSymmetricKey.hpp
  
  Index: XSECCryptoSymmetricKey.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2002-2003 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
   *
   * XSECCryptoSymmetricKey := Bulk encryption algorithms should all be
   *                                                    implemented via this 
interface
   *
   * Author(s): Berin Lautenbach
   *
   * $Id: XSECCryptoSymmetricKey.hpp,v 1.1 2003/08/31 12:48:50 blautenb Exp $
   *
   */
  
  
  
  #ifndef XSECCRYPTOSYMMETRICKEY_INCLUDE
  #define XSECCRYPTOSYMMETRICKEY_INCLUDE
  
  #include <xsec/framework/XSECDefs.hpp>
  #include <xsec/dsig/DSIGConstants.hpp>
  #include <xsec/enc/XSECCryptoKey.hpp>
  
  /**
   * \ingroup crypto
   * @{
   */
  
  /**
   * \brief Base interface definition for symmetric key material.
   *
   * All symmetric algorithms are implemented via this interface.
   * Unlike the asymmetric key definitions, this is not further
   * extended for particular algorithms.  Rather it defines
   * encrypt/decrypt functions that are implemented within particular
   * providers for a particular algorithm.
   */
  
  class DSIG_EXPORT XSECCryptoSymmetricKey : public XSECCryptoKey {
  
  public :
  
        /**
         * \brief Symmetric Key types understood by the library
         *
         * This type defines the list of symmetric key types that the library
         * understands.
         */
  
        enum SymmetricKeyType {
  
                KEY_3DES_CBC_192
  
        };
  
  
        /** @name Constructors and Destructors */
        //@{
        
        /**
         * \brief Constructor
         **/
  
        XSECCryptoSymmetricKey() {};
  
        /**
         * \brief Destructor 
         *
         * Implementations must ensure that the held key is properly destroyed
         * (overwritten) when key objects are deleted.
         */
  
        virtual ~XSECCryptoSymmetricKey() {};
  
        //@}
  
        /** @name Basic CryptoKey Interface methods */
        //@{
  
        /**
         * \brief Returns the type of this key.
         */
  
        virtual KeyType getKeyType() {return KEY_SYMMETRIC;}
  
        /**
         * \brief Returns a string that identifies the crypto owner of this 
library.
         */
  
        virtual const XMLCh * getProviderName() = 0;
  
        /**
         * \brief Clone the key
         *
         * All keys need to be able to copy themselves and return
         * a pointer to the copy.  This allows the library to 
         * duplicate keys.
         */
  
        virtual XSECCryptoKey * clone() = 0;
  
        //@}
  
        /** @name Symmetric key interface methods */
        //@{
  
        /**
         * \brief What type of symmetric key is this?
         *
         * There are a number of different types of symmetric key.
         * This method allows callers to determine the type of this
         * particular key
         */
  
        virtual SymmetricKeyType getSymmetricKeyType(void) = 0;
  
        /**
         * \brief Set the key from the provided bytes
         *
         * Symmetric keys can all be loaded from a buffer containing a series
         * of bytes.
         *
         * @param key The buffer containing the key bytes
         * @param keyLen The number of key bytes in the buffer
         *
         */
  
        virtual void setKey(const unsigned char * key, unsigned int keyLen) = 0;
  
        /**
         * \brief Initialise an decryption process
         *
         * Setup the key to get ready for a decryption session.
         * Callers can pass in an IV.  If one is not provided, 
         * but the algorithm requires one (e.g. 3DES_CBC), then 
         * implementations should assume that the start of the
         * cipher text stream will in fact be the IV.
         *
         * @param iv Initialisation Vector to be used.  NULL if one is
         * not required, or if IV will be set from data stream
         * @returns true if the initialisation succeeded.
         */
  
        virtual bool decryptInit(const unsigned char * iv = NULL) = 0;
  
        /**
         * \brief Continue an decrypt operation using this key.
         *
         * Decryption must have been set up using an encryptInit
         * call.  Takes the inBuf and continues a decryption operation,
         * writing the output to outBuf.
         *
         * This function does not have to guarantee that all input
         * will be decrypted.  In cases where the input is not a length
         * of the block size, the implementation will need to hold back
         * cipher-text to be handles during the next operation.
         *
         * @param inBuf Octets to be decrypted
         * @param plainBuf Buffer to place output in
         * @param inLength Number of bytes to decrypt
         * @param maxOutLength Maximum number of bytes to place in output 
         * buffer
         * @returns Bytes placed in output Buffer
         */
  
        virtual unsigned int decrypt(const unsigned char * inBuf, 
                                                                 unsigned char 
* plainBuf, 
                                                                 unsigned int 
inLength,
                                                                 unsigned int 
maxOutLength) = 0;
  
        /**
         * \brief Finish a decryption operation
         *
         * Complete a decryption process.  No cipher text is passed in,
         * as this should simply be removing any remaining text from
         * the plain storage buffer.
         *
         * May throw an exception if there is some stored cipher text
         * that is not the length of the block size for block algorithms.
         *
         * @param plainBuf Buffer to place any remaining plain text in
         * @param maxOutLength Maximum number of bytes to pace in output
         * @returns Bytes placed in output buffer
         */
  
        virtual unsigned int decryptFinish(unsigned char * plainBuf,
                                                                           
unsigned int maxOutLength) = 0;
  
        //@}
  
  };
  
  
  #endif /* XSECCRYPTOSYMMETRICKEY_INCLUDE */
  
  
  
  1.7       +13 -2     xml-security/c/src/enc/OpenSSL/OpenSSLCryptoProvider.cpp
  
  Index: OpenSSLCryptoProvider.cpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/OpenSSL/OpenSSLCryptoProvider.cpp,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- OpenSSLCryptoProvider.cpp 5 Jul 2003 10:30:33 -0000       1.6
  +++ OpenSSLCryptoProvider.cpp 31 Aug 2003 12:48:50 -0000      1.7
  @@ -80,7 +80,7 @@
   #include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
   #include <xsec/enc/OpenSSL/OpenSSLCryptoKeyDSA.hpp>
   #include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>
  -
  +#include <xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.hpp>
   
   OpenSSLCryptoProvider::OpenSSLCryptoProvider() {
   
  @@ -174,5 +174,16 @@
        return ret;
   
   }
  +
  +XSECCryptoSymmetricKey       * 
OpenSSLCryptoProvider::keySymmetric(XSECCryptoSymmetricKey::SymmetricKeyType 
alg) {
  +
  +     OpenSSLCryptoSymmetricKey * ret;
  +
  +     XSECnew(ret, OpenSSLCryptoSymmetricKey(alg));
  +
  +     return ret;
  +
  +}
  +
   
   #endif /* HAVE_OPENSSL */
  
  
  
  1.7       +13 -1     xml-security/c/src/enc/OpenSSL/OpenSSLCryptoProvider.hpp
  
  Index: OpenSSLCryptoProvider.hpp
  ===================================================================
  RCS file: /home/cvs/xml-security/c/src/enc/OpenSSL/OpenSSLCryptoProvider.hpp,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- OpenSSLCryptoProvider.hpp 5 Jul 2003 10:30:33 -0000       1.6
  +++ OpenSSLCryptoProvider.hpp 31 Aug 2003 12:48:50 -0000      1.7
  @@ -217,6 +217,18 @@
   
        virtual XSECCryptoX509                  * X509();
   
  +     /**
  +      * \brief Return a Symmetric Key implementation object.
  +      *
  +      * Call used by the library to obtain a bulk encryption
  +      * object.
  +      *
  +      * @returns Pointer to the new SymmetricKey object
  +      * @see XSECCryptoSymmetricKey
  +      */
  +
  +     virtual XSECCryptoSymmetricKey  * 
keySymmetric(XSECCryptoSymmetricKey::SymmetricKeyType alg);
  +
        //@}
   
        /[EMAIL PROTECTED]/
  
  
  
  1.1                  
xml-security/c/src/enc/OpenSSL/OpenSSLCryptoSymmetricKey.cpp
  
  Index: OpenSSLCryptoSymmetricKey.cpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2002-2003 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
   *
   * XSECCryptoSymmetricKey := Bulk encryption algorithms should all be
   *                                                    implemented via this 
interface
   *
   * Author(s): Berin Lautenbach
   *
   * $Id: OpenSSLCryptoSymmetricKey.cpp,v 1.1 2003/08/31 12:48:50 blautenb Exp $
   *
   */
  
  #include <xsec/framework/XSECDefs.hpp>
  #include <xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.hpp>
  #include <xsec/framework/XSECError.hpp>
  #include <xsec/enc/XSECCryptoException.hpp>
  
  // 
--------------------------------------------------------------------------------
  //           Constructors and Destructors
  // 
--------------------------------------------------------------------------------
  
  
OpenSSLCryptoSymmetricKey::OpenSSLCryptoSymmetricKey(XSECCryptoSymmetricKey::SymmetricKeyType
 type) :
  m_keyType(type),
  m_keyBuf(""),
  m_keyLen(0),
  m_initialised(false) {
  
        EVP_CIPHER_CTX_init(&m_ctx);
        m_keyBuf.isSensitive();
  
  }
  
  OpenSSLCryptoSymmetricKey::~OpenSSLCryptoSymmetricKey() {
  
        // Clean up the context
  
        EVP_CIPHER_CTX_cleanup(&m_ctx);
  }
  
  // 
--------------------------------------------------------------------------------
  //           Basic Key interface methods
  // 
--------------------------------------------------------------------------------
  
  XSECCryptoSymmetricKey::SymmetricKeyType 
OpenSSLCryptoSymmetricKey::getSymmetricKeyType() {
  
        return m_keyType;
  
  }
  
  const XMLCh * OpenSSLCryptoSymmetricKey::getProviderName() {
  
        return DSIGConstants::s_unicodeStrPROVOpenSSL;
  
  }
  
  XSECCryptoKey * OpenSSLCryptoSymmetricKey::clone() {
  
        OpenSSLCryptoSymmetricKey * ret;
  
        XSECnew(ret, OpenSSLCryptoSymmetricKey(m_keyType));
        ret->m_keyLen = m_keyLen;
        ret->m_keyBuf = m_keyBuf;
  
        return ret;
  
  }
  
  // 
--------------------------------------------------------------------------------
  //           Store the key value
  // 
--------------------------------------------------------------------------------
  
  void OpenSSLCryptoSymmetricKey::setKey(const unsigned char * key, unsigned 
int keyLen) {
  
        m_keyBuf.sbMemcpyIn(key, keyLen);
        m_keyLen = keyLen;
  
  }
  
  // 
--------------------------------------------------------------------------------
  //           Decrypt
  // 
--------------------------------------------------------------------------------
  
  int OpenSSLCryptoSymmetricKey::decryptCtxInit(const unsigned char * iv) {
  
        // Returns amount of IV data used (in bytes)
        // Sets m_initialised iff the key is OK and the IV is OK.
  
        if (m_initialised)
                return 0;
  
        if (m_keyLen == 0) {
  
                throw XSECCryptoException(XSECCryptoException::SymmetricError,
                        "OpenSSL:SymmetricKey - Cannot initialise without 
key"); 
  
        }
  
        // Set up the context according to the required cipher type
  
        switch (m_keyType) {
  
        case (XSECCryptoSymmetricKey::KEY_3DES_CBC_192) :
  
                // A 3DES key
  
                if (iv == NULL) {
  
                        return 0;       // Cannot initialise without an IV
  
                }
  
                EVP_DecryptInit_ex(&m_ctx, EVP_des_ede3_cbc(), NULL, 
m_keyBuf.rawBuffer(), iv);
                // Turn off padding
                EVP_CIPHER_CTX_set_padding(&m_ctx, 0);
  
                // That means we have to handle padding, so we always hold back
                // 8 bytes of data.
                m_blockSize = 8;
                m_bytesInLastBlock = 0;
  
                return 8;       // 3DEC_CBC uses a 64 bit IV
  
                break;
  
        default :
  
                // Cannot do this without an IV
                throw XSECCryptoException(XSECCryptoException::SymmetricError,
                        "OpenSSL:SymmetricKey - Unknown key type"); 
  
        }
  
        return 0;
  }
  
  
  bool OpenSSLCryptoSymmetricKey::decryptInit(const unsigned char * iv) {
  
        decryptCtxInit(iv);
  
        return true;
  
  }
  
  unsigned int OpenSSLCryptoSymmetricKey::decrypt(const unsigned char * inBuf, 
                                                                 unsigned char 
* plainBuf, 
                                                                 unsigned int 
inLength,
                                                                 unsigned int 
maxOutLength) {
  
  
  
        // NOTE: This won't actually stop OpenSSL blowing the buffer, so the 
onus is
        // on the caller.
  
        unsigned int offset = 0;
        if (!m_initialised) {
                offset = decryptCtxInit(inBuf);
                if (offset > inLength) {
                        throw 
XSECCryptoException(XSECCryptoException::SymmetricError,
                        "OpenSSL:SymmetricKey - Not enough data passed in to 
get IV");
                }
        }
  
        int outl = maxOutLength;
  
        if (EVP_DecryptUpdate(&m_ctx, &plainBuf[m_bytesInLastBlock], &outl, 
&inBuf[offset], inLength - m_bytesInLastBlock - offset) == 0) {
  
                throw XSECCryptoException(XSECCryptoException::SymmetricError,
                        "OpenSSL:SymmetricKey - Error during OpenSSL decrypt"); 
  
        }
  
        // Store the last block
        if (m_blockSize > 0 && outl >= m_blockSize) {
  
                // Output will always be *at least* the blocksize
  
                // Copy the previous last block into the start of the output 
buffer
                memcpy(plainBuf, m_lastBlock, m_bytesInLastBlock);
  
                // Copy the tail into the buffer
                memcpy(m_lastBlock, &plainBuf[outl + m_bytesInLastBlock - 
m_blockSize], m_blockSize);
  
                outl = outl + m_bytesInLastBlock - m_blockSize;
                m_bytesInLastBlock = m_blockSize;
  
        }
  
        return outl;
  
  }
  
  unsigned int OpenSSLCryptoSymmetricKey::decryptFinish(unsigned char * 
plainBuf,
                                                                                
                          unsigned int maxOutLength) {
  
        int outl = maxOutLength;
  
        if (EVP_DecryptFinal_ex(&m_ctx, plainBuf, &outl) == 0) {
  
                throw XSECCryptoException(XSECCryptoException::SymmetricError,
                        "OpenSSL:SymmetricKey - Error during OpenSSL decrypt 
finalisation"); 
  
        }
  
        if (outl > 0) {
        
                // Should never see any bytes output, as we are not padding
  
                throw XSECCryptoException(XSECCryptoException::SymmetricError,
                        "OpenSSL:SymmetricKey - Unexpectedly recieved bytes 
from EVP_DecryptFinal_ex"); 
  
        }
  
        // Calculate any padding issues
        if (m_bytesInLastBlock == m_blockSize) {
  
                outl = m_blockSize - m_lastBlock[m_blockSize - 1];
  
                if (outl > m_blockSize || outl < 0) {
                        
                        throw 
XSECCryptoException(XSECCryptoException::SymmetricError,
                                "OpenSSL:SymmetricKey::decryptFinish - Out of 
range padding value in final block"); 
        
                }
  
                memcpy(plainBuf, m_lastBlock, outl);
  
        }
  
        return outl;
  
  }
  
  
  
  
  1.1                  
xml-security/c/src/enc/OpenSSL/OpenSSLCryptoSymmetricKey.hpp
  
  Index: OpenSSLCryptoSymmetricKey.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2002-2003 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
   *
   * XSECCryptoSymmetricKey := Bulk encryption algorithms should all be
   *                                                    implemented via this 
interface
   *
   * Author(s): Berin Lautenbach
   *
   * $Id: OpenSSLCryptoSymmetricKey.hpp,v 1.1 2003/08/31 12:48:50 blautenb Exp $
   *
   */
  
  
  
  #ifndef OPENSSLCRYPTOSYMMETRICKEY_INCLUDE
  #define OPENSSLCRYPTOSYMMETRICKEY_INCLUDE
  
  #include <xsec/framework/XSECDefs.hpp>
  #include <xsec/enc/XSECCryptoSymmetricKey.hpp>
  
  // OpenSSL Includes
  
  #include <openssl/evp.h>
  
  #define MAX_BLOCK_SIZE                8
  
  /**
   * \ingroup opensslcrypto
   * @{
   */
  
  /**
   * \brief Base interface definition for symmetric key material.
   *
   * This is the implementation for a wrapper of OpenSSL symmetric
   * crypto functions.
   */
  
  class DSIG_EXPORT OpenSSLCryptoSymmetricKey : public XSECCryptoSymmetricKey {
  
  public :
  
        /** @name Constructors and Destructors */
        //@{
        
        /**
         * \brief Constructor
         *
         * Can only construct a Symmetric key if we know what type it is
         **/
  
        OpenSSLCryptoSymmetricKey(XSECCryptoSymmetricKey::SymmetricKeyType 
type);
  
        /**
         * \brief Destructor 
         *
         * Implementations must ensure that the held key is properly destroyed
         * (overwritten) when key objects are deleted.
         */
  
        virtual ~OpenSSLCryptoSymmetricKey();
  
        //@}
  
        /** @name Basic CryptoKey Interface methods */
        //@{
  
        /**
         * \brief Returns a string that identifies the crypto owner of this 
library.
         */
  
        virtual const XMLCh * getProviderName();
  
        /**
         * \brief Clone the key
         *
         * All keys need to be able to copy themselves and return
         * a pointer to the copy.  This allows the library to 
         * duplicate keys.
         */
  
        virtual XSECCryptoKey * clone();
  
        //@}
  
        /** @name Symmetric key interface methods */
        //@{
  
        /**
         * \brief What type of symmetric key is this?
         *
         * There are a number of different types of symmetric key.
         * This method allows callers to determine the type of this
         * particular key
         */
  
        SymmetricKeyType getSymmetricKeyType(void);
  
        /**
         * \brief Set the key from the provided bytes
         *
         * Symmetric keys can all be loaded from a buffer containing a series
         * of bytes.
         *
         * @param key The buffer containing the key bytes
         * @param keyLen The number of key bytes in the buffer
         *
         */
  
        void setKey(const unsigned char * key, unsigned int keyLen);
  
        /**
         * \brief Initialise an decryption process
         *
         * Setup the key to get ready for a decryption session.
         * Callers can pass in an IV.  If one is not provided, 
         * then it is assumed that the algorithm will not require one.
         *
         * @param iv Initialisation Vector to be used.  NULL if one is
         * not required.
         * @returns true if the initialisation succeeded.
         */
  
        virtual bool decryptInit(const unsigned char * iv = NULL);
  
        /**
         * \brief Continue an decrypt operation using this key.
         *
         * Decryption must have been set up using an encryptInit
         * call.  Takes the inBuf and continues a decryption operation,
         * writing the output to outBuf.
         *
         * This function does not have to guarantee that all input
         * will be decrypted.  In cases where the input is not a length
         * of the block size, the implementation will need to hold back
         * cipher-text to be handles during the next operation.
         *
         * @note While maxOutLength is defined, the OpenSSL libraries will
         * not read the value, so the onus is on the caller to ensure the
         * buffer is long enough to hold the output!
         *
         * @param inBuf Octets to be decrypted
         * @param plainBuf Buffer to place output in
         * @param inLength Number of bytes to decrypt
         * @param maxOutLength Maximum number of bytes to place in output 
         * buffer
         * @returns Bytes placed in output Buffer
         */
  
        virtual unsigned int decrypt(const unsigned char * inBuf, 
                                                                 unsigned char 
* plainBuf, 
                                                                 unsigned int 
inLength,
                                                                 unsigned int 
maxOutLength);
  
        /**
         * \brief Finish a decryption operation
         *
         * Complete a decryption process.  No cipher text is passed in,
         * as this should simply be removing any remaining text from
         * the plain storage buffer.
         *
         * May throw an exception if there is some stored cipher text
         * that is not the length of the block size for block algorithms.
         *
         * @note While maxOutLength is defined, the OpenSSL libraries will
         * not read the value, so the onus is on the caller to ensure the
         * buffer is long enough to hold the output!
         *
         * @param plainBuf Buffer to place any remaining plain text in
         * @param maxOutLength Maximum number of bytes to pace in output
         * @returns Bytes placed in output buffer
         */
  
        virtual unsigned int decryptFinish(unsigned char * plainBuf,
                                                                           
unsigned int maxOutLength);
  
        //@}
  
  private:
  
        // Unimplemented constructors
        
        OpenSSLCryptoSymmetricKey();
        OpenSSLCryptoSymmetricKey(const OpenSSLCryptoSymmetricKey &);
        OpenSSLCryptoSymmetricKey & operator= (const OpenSSLCryptoSymmetricKey 
&);
  
        // Private functions
        int decryptCtxInit(const unsigned char * iv);
  
        // Private variables
        SymmetricKeyType                                m_keyType;
        EVP_CIPHER_CTX                                  m_ctx;                  
// OpenSSL Cipher Context structure
        safeBuffer                                              m_keyBuf;       
        // Holder of the key
        unsigned int                                    m_keyLen;
        bool                                                    m_initialised;  
// Is the context ready to work?
        unsigned char                                   
m_lastBlock[MAX_BLOCK_SIZE];
        int                                                             
m_blockSize;
        int                                                             
m_bytesInLastBlock;
  
  };
  
  
  #endif /* OPENSSLCRYPTOSYMMETRICKEY_INCLUDE */
  
  
  

Reply via email to