blautenb    2003/04/07 05:11:54

  Added:       c/src/enc/XSCrypt XSCryptCryptoBase64.cpp
                        XSCryptCryptoBase64.hpp
  Log:
  Internal implementation of Base64 encode/decode
  
  Revision  Changes    Path
  1.1                  xml-security/c/src/enc/XSCrypt/XSCryptCryptoBase64.cpp
  
  Index: XSCryptCryptoBase64.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
   *
   * XSCryptCryptoBase64 := Internal implementation of a base64 
   * encoder/decoder
   *
   * Author(s): Berin Lautenbach
   *
   * $Id: XSCryptCryptoBase64.cpp,v 1.1 2003/04/07 12:11:54 blautenb Exp $
   *
   */
  
  #include <xsec/enc/XSCrypt/XSCryptCryptoBase64.hpp>
  #include <xsec/enc/XSECCryptoException.hpp>
  
  // 
--------------------------------------------------------------------------------
  //           Lookup tables and macros
  // 
--------------------------------------------------------------------------------
  
  char Base64LookupTable[] = {
        'A','B','C','D','E','F','G','H','I','J','K','L','M',
        'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
        'a','b','c','d','e','f','g','h','i','j','k','l','m',
        'n','o','p','q','r','s','t','u','v','w','x','y','z',
        '0','1','2','3','4','5','6','7','8','9','+','/',
  };
  
  #define IS_UPPER(c) (c >= 'A' && c <= 'Z')
  #define IS_LOWER(c) (c >= 'a' && c <= 'z')
  #define IS_NUMBR(c) (c >= '0' && c <= '9')
  #define IS_OTHER(c) (c == '+' || c == '/')
  #define IS_B64CH(c) (IS_LOWER(c) || IS_UPPER(c) || IS_NUMBR(c) || IS_OTHER(c))
  #define IS_B64OE(c) (IS_B64CH(c) || c == '=')
  
  // 
--------------------------------------------------------------------------------
  //           Decoding
  // 
--------------------------------------------------------------------------------
  
  unsigned char decodeCh(unsigned char c) {
  
        if (IS_UPPER(c))
                return c - 'A';
  
        if (IS_LOWER(c))
                return (c - 'a') + 26;
  
        if (IS_NUMBR(c))
                return (c - '0') + 52;
  
        if (c == '+')
                return 62;
        if (c == '/')
                return 63;
  
        if (c == '=')
                return 64;
  
        return 65;              // error;
  
  }
  
  void XSCryptCryptoBase64::canonicaliseInput(unsigned char *inData, 
                                                                                
        unsigned int inLength) {
  
        // Canonicalise the input buffer into m_inputBuffer
  
        unsigned char buf[400];                 // Do 400 bytes at a time
  
        unsigned int i, j;
        j = 0;
  
        for (i = 0; i < inLength; ++i) {
  
                if (IS_B64OE(inData[i])) {
  
                        // Have a base64 or '=' char
                        buf[j++] = inData[i];
  
                        if (j == 400) {
                                m_inputBuffer.sbMemcpyIn(m_remainingInput, buf, 
400);
                                m_remainingInput += 400;
                                j = 0;
                        }
                }
        }
  
        if (j > 0) {
                m_inputBuffer.sbMemcpyIn(m_remainingInput, buf, j);
                m_remainingInput += j;
        }
  
  }
  
  
  void XSCryptCryptoBase64::decodeInit(void) {
  
        m_remainingInput = m_remainingOutput = 0;
        m_allDone = false;
        m_state = B64_DECODE;
  
  }
  
  unsigned int XSCryptCryptoBase64::decode(unsigned char * inData, 
                                                            unsigned int 
inLength,
                                                                unsigned char * 
outData,
                                                                unsigned int 
outLength) {
  
  
        // Ensure we are in an appropriate state
        if (m_state != B64_DECODE) {
  
                throw XSECCryptoException(XSECCryptoException::Base64Error,
                        "XSCrypt:Base64 - Attempt to decode when not in decode 
state");
        
        }
  
        // Copy the data into our input buffer
        canonicaliseInput(inData, inLength);
  
        unsigned int i = 0;
        unsigned char t;
  
        while (m_allDone != true && m_remainingInput - i >= 4) {
  
                // BYTE 1
  
                t = decodeCh(m_inputBuffer[i++]);
  
                if (t > 63) {
  
                        throw 
XSECCryptoException(XSECCryptoException::Base64Error,
                        "XSCrypt:Base64 - Invalid character at start of base 64 
block");
  
                }
  
                m_outputBuffer[m_remainingOutput] = (t << 2);
  
                // BYTE 2
  
                t = decodeCh(m_inputBuffer[i++]);
  
                if (t > 63) {
  
                        throw 
XSECCryptoException(XSECCryptoException::Base64Error,
                        "XSCrypt:Base64 - Invalid character at start of base 64 
block");
  
                }
  
                // Take top two bits and place at end of current byte
                m_outputBuffer[m_remainingOutput] = 
m_outputBuffer[m_remainingOutput] |
                        (t >> 4);
  
                m_remainingOutput++;            // Have a new complete byte
  
                // Take remaining 4 bits and add to outputBuffer
                m_outputBuffer[m_remainingOutput] = ( t << 4);
  
                // BYTE 3
  
                t = decodeCh(m_inputBuffer[i++]);
  
                if (t > 64) {
  
                        throw 
XSECCryptoException(XSECCryptoException::Base64Error,
                        "XSCrypt:Base64 - Invalid character at start of base 64 
block");
  
                }
  
                if (t == 64) {
  
                        // '=' character found
  
                        m_allDone = true;
                        break;
  
                }
  
                // Take 4 bits and append to current buffer
  
                m_outputBuffer[m_remainingOutput] = 
m_outputBuffer[m_remainingOutput] | (t >> 2);
                m_remainingOutput++;
  
                // Take last 2 bits and append to buffer
  
                m_outputBuffer[m_remainingOutput] = (t << 6);
  
                // BYTE 4
  
                t = decodeCh(m_inputBuffer[i++]);
  
                if (t > 64) {
  
                        throw 
XSECCryptoException(XSECCryptoException::Base64Error,
                        "XSCrypt:Base64 - Invalid character at start of base 64 
block");
  
                }
  
                if (t == 64) {
  
                        m_allDone = true;
                        break;
  
                }
  
                // Place all six bits and end of current byte
  
                m_outputBuffer[m_remainingOutput] = 
m_outputBuffer[m_remainingOutput] | t;
                m_remainingOutput++;
  
        }
  
        // Now whatever we've decoded can be placed in the output buffer
  
        unsigned int cpyOut = (m_remainingOutput < outLength ? 
m_remainingOutput : outLength);
  
        m_outputBuffer.sbMemcpyOut(outData, cpyOut);
  
        // Move the buffers down
        if (cpyOut != m_remainingOutput) {
                m_remainingOutput = m_remainingOutput - cpyOut;
                m_outputBuffer.sbMemshift(0, cpyOut, m_remainingOutput);
        }
        else
                m_remainingOutput = 0;
  
        if (i != m_remainingInput) {
                m_remainingInput -= i;
                m_inputBuffer.sbMemshift(0, i, m_remainingInput);
        }
        else
                m_remainingInput = 0;
  
        // Return however much we have decoded
        return cpyOut;
  
  }
  
  unsigned int XSCryptCryptoBase64::decodeFinish(unsigned char * outData,
                                                                      unsigned 
int outLength) {
  
        if (m_state != B64_DECODE) {
  
                throw XSECCryptoException(XSECCryptoException::Base64Error,
                        "XSCrypt:Base64 - Attempt to complete a decode when not 
in decode state");
        
        }
  
        m_allDone = true;
        unsigned int cpyOut = (m_remainingOutput < outLength ? 
m_remainingOutput : outLength);
  
        m_outputBuffer.sbMemcpyOut(outData, cpyOut);
  
        // Move the buffers down
        if (cpyOut != m_remainingOutput) {
                m_remainingOutput = m_remainingOutput - cpyOut;
                m_outputBuffer.sbMemshift(0, cpyOut, m_remainingOutput);
        }
        else {
                m_remainingOutput = 0;
        }
  
        return cpyOut;
  }
  
  // 
--------------------------------------------------------------------------------
  //           Encoding
  // 
--------------------------------------------------------------------------------
  
  void XSCryptCryptoBase64::encodeInit(void) {
  
        m_remainingInput = m_remainingOutput = 0;
        m_allDone = false;
        m_charCount = 0;
        m_state = B64_ENCODE;
  
  }
  
  
  unsigned int XSCryptCryptoBase64::encode(unsigned char * inData, 
                                                            unsigned int 
inLength,
                                                                unsigned char * 
outData,
                                                                unsigned int 
outLength) {
  
        if (m_state != B64_ENCODE) {
  
                throw XSECCryptoException(XSECCryptoException::Base64Error,
                        "XSCrypt:Base64 - Attempt to encode when not in 
encoding state");
        
        }
  
        // Copy input data into end of input buffer
        m_inputBuffer.sbMemcpyIn(m_remainingInput, inData, inLength);
        m_remainingInput += inLength;
  
        unsigned int i = 0;
        unsigned char t;
  
        while (m_allDone == false && m_remainingInput - i >= 3) {
  
                // Have a complete block of three bytes to encode
  
                // First 6 bits;
                t = (m_inputBuffer[i] >> 2);
                m_outputBuffer[m_remainingOutput++] = Base64LookupTable[t];
  
                // 2 bits from byte one and 4 from byte 2
                t = ((m_inputBuffer[i++] << 4) & 0x30) | (m_inputBuffer[i] >> 
4);
                m_outputBuffer[m_remainingOutput++] = Base64LookupTable[t];
  
                // 4 from byte 2 and 2 from byte 3
                t = ((m_inputBuffer[i++] << 2) & 0x3C) | (m_inputBuffer[i] >> 
6);
                m_outputBuffer[m_remainingOutput++] = Base64LookupTable[t];
  
                // last 6 bits from byte 3
                t = m_inputBuffer[i++] & 0x3F;
                m_outputBuffer[m_remainingOutput++] = Base64LookupTable[t];
  
                m_charCount += 4;
  
                if (m_charCount >= 76) {
  
                        m_outputBuffer[m_remainingOutput++] = '\n';
                        m_charCount = 0;
                
                }
  
        }
  
        // Now copy data out to output buffer
  
        unsigned int cpyOut = (m_remainingOutput < outLength ? 
m_remainingOutput : outLength);
  
        m_outputBuffer.sbMemcpyOut(outData, cpyOut);
  
        // Move the buffers down
        if (cpyOut != m_remainingOutput) {
                m_remainingOutput = m_remainingOutput - cpyOut;
                m_outputBuffer.sbMemshift(0, cpyOut, m_remainingOutput);
        }
        else
                m_remainingOutput = 0;
  
        if (i != m_remainingInput) {
                m_remainingInput -= i;
                m_inputBuffer.sbMemshift(0, i, m_remainingInput);
        }
  
        else
  
                m_remainingInput = 0;
  
        // Return however much we have decoded
        return cpyOut;
  
  }
  
  unsigned int XSCryptCryptoBase64::encodeFinish(unsigned char * outData,
                                                                      unsigned 
int outLength) {
  
        if (m_state != B64_ENCODE) {
  
                throw XSECCryptoException(XSECCryptoException::Base64Error,
                        "XSCrypt:Base64 - Attempt to complete an encode when 
not in encoding state");
        
        }
  
        if (m_allDone == false && m_remainingInput > 0) {
  
                // Will always be < 3 characters remaining in inputBuffer
                // If necessary - terminate the Base64 string
  
                if (m_remainingInput >= 3) {
  
                        throw 
XSECCryptoException(XSECCryptoException::Base64Error,
                                "XSCrypt:Base64 - Too much remaining input in 
input buffer");
  
                }
  
                // First 6 bits;
                unsigned int t = (m_inputBuffer[0] >> 2);
                m_outputBuffer[m_remainingOutput++] = Base64LookupTable[t];
  
                // 2 bits from byte one and 4 from byte 2
                t = ((m_inputBuffer[0] << 4) & 0x30);
                
                if (m_remainingInput == 1) {
                        m_outputBuffer[m_remainingOutput++] = 
Base64LookupTable[t];
                        m_outputBuffer[m_remainingOutput++] = '=';
                        m_outputBuffer[m_remainingOutput++] = '=';
                }
  
                else {
  
                        t |= (m_inputBuffer[1] >> 4);
                        m_outputBuffer[m_remainingOutput++] = 
Base64LookupTable[t];
  
                        // 4 from byte 2
                        t = ((m_inputBuffer[1] << 2) & 0x3C);
                        m_outputBuffer[m_remainingOutput++] = 
Base64LookupTable[t];
                        m_outputBuffer[m_remainingOutput++] = '=';
                }
  
        }
  
        m_allDone = true;
  
        // Copy out
        unsigned int cpyOut = (m_remainingOutput < outLength ? 
m_remainingOutput : outLength);
  
        m_outputBuffer.sbMemcpyOut(outData, cpyOut);
  
        // Move the buffers down
        if (cpyOut != m_remainingOutput) {
                m_remainingOutput = m_remainingOutput - cpyOut;
                m_outputBuffer.sbMemshift(0, cpyOut, m_remainingOutput);
        }
        else {
                m_remainingOutput = 0;
        }
  
        return cpyOut;
  }
  
  
  
  1.1                  xml-security/c/src/enc/XSCrypt/XSCryptCryptoBase64.hpp
  
  Index: XSCryptCryptoBase64.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
   *
   * XSCryptCryptoBase64 := Internal implementation of a base64 encoder/decoder
   *
   * Author(s): Berin Lautenbach
   *
   * $Id: XSCryptCryptoBase64.hpp,v 1.1 2003/04/07 12:11:54 blautenb Exp $
   *
   */
  
  #ifndef XSCRYPTCRYPTOBASE64_INCLUDE
  #define XSCRYPTCRYPTOBASE64_INCLUDE
  
  #include <xsec/framework/XSECDefs.hpp>
  #include <xsec/enc/XSECCryptoBase64.hpp>
  #include <xsec/utils/XSECSafeBuffer.hpp>
  
  class DSIG_EXPORT XSCryptCryptoBase64 : public XSECCryptoBase64 {
  
  
  public :
  
        // Constructors/Destructors
        
        XSCryptCryptoBase64() : m_state(B64_UNINITIALISED) {};
        virtual ~XSCryptCryptoBase64() {};
  
        // Decoding Activities
        virtual void             decodeInit(void);                              
        // Setup
        virtual unsigned int decode(unsigned char * inData, 
                                                            unsigned int 
inLength,
                                                                unsigned char * 
outData,
                                                                unsigned int 
outLength);        // decode
        virtual unsigned int decodeFinish(unsigned char * outData,
                                                                      unsigned 
int outLength);// Finish
  
        // Encoding activities
        virtual void             encodeInit(void);                              
                // Setup
        virtual unsigned int encode(unsigned char * inData, 
                                                            unsigned int 
inLength,
                                                                unsigned char * 
outData,
                                                                unsigned int 
outLength);                // decode
        virtual unsigned int encodeFinish(unsigned char * outData,
                                                                      unsigned 
int outLength);  // Finish
  
  private :
  
        enum b64state {
  
                B64_UNINITIALISED,
                B64_ENCODE,
                B64_DECODE,
        };
  
        safeBuffer                              m_inputBuffer;          // 
Carry over buffer
        safeBuffer                              m_outputBuffer;         // 
Carry over output
  
        unsigned int                    m_remainingInput;       // Number of 
bytes in carry input buffer
        unsigned int                    m_remainingOutput;      // Number of 
bytes in carry output buffer
  
        bool                                    m_allDone;                      
// End found (=)
  
        b64state                                m_state;                        
// What are we currently doing?
  
        unsigned int                    m_charCount;            // How many 
characters in current line?
  
        // Private functions
        void canonicaliseInput(unsigned char *inData, unsigned int inLength);
  
  };
  
  #endif /* XSCRYPTCRYPTOBASE64_INCLUDE */
  
  
  

Reply via email to