protected byte[] InternalEncryptBytes(byte[] buffer, int offset, int size, ContentType type)           // only accepts sizes of less than 16Kb; does not do any error checking
        {
            byte[] bytes = new byte[size];
            Array.Copy(buffer, offset, bytes, 0, size);
            RecordMessage message = new RecordMessage(MessageType.PlainText, type, m_HandshakeLayer.GetVersion(), bytes);

            WrapMessage(message);
            return(message.ToBytes());
        }
Beispiel #2
0
		} //*/
		protected void UnwrapMessage(RecordMessage message) {
			if (message.length != message.fragment.Length)
				throw new SslException(AlertDescription.IllegalParameter, "Message length is invalid.");
			byte[] remoteMac = null, decrypted = null, localMac = null;
			bool cipherError = false;
			// decrypt and verify the message
			if (m_BulkDecryption != null) {
				if (message.length <= m_RemoteHasher.HashSize / 8)
					throw new SslException(AlertDescription.DecodeError, "Message is too small.");
				if (message.length % m_BulkDecryption.OutputBlockSize != 0)
					throw new SslException(AlertDescription.DecryptError, "Message length is invalid.");
				// decrypt the message
				if (m_BulkDecryption.OutputBlockSize == 1) { // is stream cipher?
					decrypted = new byte[message.length];
					m_BulkDecryption.TransformBlock(message.fragment, 0, message.length, decrypted, 0);
					remoteMac = new byte[m_RemoteHasher.HashSize / 8];
					Array.Copy(decrypted, message.length - remoteMac.Length, remoteMac, 0, remoteMac.Length);
					message.fragment = new byte[decrypted.Length - remoteMac.Length];
					Array.Copy(decrypted, 0, message.fragment, 0, message.fragment.Length);
					message.length = (ushort)message.fragment.Length;
				} else { // cipher is block cipher
					decrypted = new byte[message.fragment.Length];
					m_BulkDecryption.TransformBlock(message.fragment, 0, decrypted.Length, decrypted, 0);
					byte padding = decrypted[decrypted.Length - 1];
					if (message.length < padding + m_RemoteHasher.HashSize / 8 + 1) {
						cipherError = true;
						remoteMac = new byte[m_RemoteHasher.HashSize / 8];
					} else {
						int realSize = (message.length - padding) - 1;
						remoteMac = new byte[m_RemoteHasher.HashSize / 8];
						Array.Copy(decrypted, realSize - remoteMac.Length, remoteMac, 0, remoteMac.Length);
						message.fragment = new byte[realSize - remoteMac.Length];
						Array.Copy(decrypted, 0, message.fragment, 0, message.fragment.Length);
						message.length = (ushort)message.fragment.Length;
						if (m_HandshakeLayer.GetProtocol() == SecureProtocol.Tls1) {
							// check padding
							for(int i = realSize; i < decrypted.Length; i++) {
								if (decrypted[i] != padding) {
									cipherError = true;
								}
							}
						}
					}
				}
				// calculate the MAC
				localMac = GetULongBytes(m_InputSequenceNumber);
				m_RemoteHasher.Initialize();
				m_RemoteHasher.TransformBlock(localMac, 0, localMac.Length, localMac, 0);	// seq_num + ..
				localMac = message.ToBytes();
				if (m_HandshakeLayer.GetProtocol() == SecureProtocol.Tls1) {
					m_RemoteHasher.TransformFinalBlock(localMac, 0, localMac.Length);		// .. + TLSCompressed.type + TLSCompressed.version + TLSCompressed.length + TLSCompressed.fragment
				} else if (m_HandshakeLayer.GetProtocol() == SecureProtocol.Ssl3) {
					m_RemoteHasher.TransformBlock(localMac, 0, 1, localMac, 0); // type
					m_RemoteHasher.TransformFinalBlock(localMac, 3, localMac.Length - 3); // length + fragment
				} else {
					throw new NotSupportedException("Only SSL3 and TLS1 are supported");
				}
				localMac = m_RemoteHasher.Hash;
				// compare MACs
				for(int i = 0; i < remoteMac.Length; i++) {
					if (remoteMac[i] != localMac[i]) {
						cipherError = true;
					}
				}
				// throw cipher error, if necessary
				if (cipherError)
					throw new SslException(AlertDescription.BadRecordMac, "An error occurred during the decryption and verification process.");
			}
			// decompress the message
			if (m_RemoteCompressor != null) {
				message.fragment = m_RemoteCompressor.Decompress(message.fragment);
				message.length = (ushort)message.fragment.Length;
			}
			// final adjustments
			message.messageType = MessageType.PlainText;
			m_InputSequenceNumber++;
		}
Beispiel #3
0
		protected void WrapMessage(RecordMessage message) {
			if (message.length != message.fragment.Length)
				throw new SslException(AlertDescription.IllegalParameter, "Message length is invalid.");
			byte[] mac = null;
			try {
				// compress the message
				if (m_LocalCompressor != null) {
					message.fragment = m_LocalCompressor.Compress(message.fragment);
					message.length = (ushort)message.fragment.Length;
				}
				// encrypt the message and MAC
				if (m_LocalHasher != null) {
					// calculate the MAC
					mac = GetULongBytes(m_OutputSequenceNumber);
					m_LocalHasher.Initialize();
					m_LocalHasher.TransformBlock(mac, 0, mac.Length, mac, 0);	// seq_num + ..
					mac = message.ToBytes();
					if (m_HandshakeLayer.GetProtocol() == SecureProtocol.Tls1) {
						m_LocalHasher.TransformFinalBlock(mac, 0, mac.Length);		// .. + TLSCompressed.type + TLSCompressed.version + TLSCompressed.length + TLSCompressed.fragment
					} else if (m_HandshakeLayer.GetProtocol() == SecureProtocol.Ssl3) {
						m_LocalHasher.TransformBlock(mac, 0, 1, mac, 0); // type
						m_LocalHasher.TransformFinalBlock(mac, 3, mac.Length - 3); // length + fragment
					} else {
						throw new NotSupportedException("Only SSL3 and TLS1 are supported");
					}
					mac = m_LocalHasher.Hash;
					// encrypt the message
					if (m_BulkEncryption.OutputBlockSize == 1) { // is stream cipher?
						byte[] ret = new byte[message.length + mac.Length];
						m_BulkEncryption.TransformBlock(message.fragment, 0, message.length, ret, 0);
						m_BulkEncryption.TransformBlock(mac, 0, mac.Length, ret, message.length);
						message.fragment = ret;
					} else { // cipher is block cipher
						int obs = m_BulkEncryption.OutputBlockSize;
						byte padding = (byte)((obs - (message.length + mac.Length + 1) % obs) % obs);
						byte[] ret = new byte[message.length + mac.Length + padding + 1];
						Array.Copy(message.fragment, 0, ret, 0, message.length);
						Array.Copy(mac, 0, ret, message.length, mac.Length);
						if (m_HandshakeLayer.GetProtocol() == SecureProtocol.Tls1) {
							for(int i = message.length + mac.Length; i < ret.Length; i++) {
								ret[i] = padding;
							}
						} else {
							byte[] buffer = new byte[ret.Length - message.length - mac.Length];
							m_HandshakeLayer.RNG.GetBytes(buffer);
							Array.Copy(buffer, 0, ret, message.length + mac.Length, buffer.Length);
							ret[ret.Length - 1] = padding;
						}
						m_BulkEncryption.TransformBlock(ret, 0, ret.Length, ret, 0);
						message.fragment = ret;
					}
					message.length = (ushort)message.fragment.Length;
				}
			} catch (Exception e) {
				throw new SslException(e, AlertDescription.InternalError, "An exception occurred");
			}
			// final adjustments
			message.messageType = MessageType.Encrypted;
			m_OutputSequenceNumber++;
		} //*/
Beispiel #4
0
		protected byte[] InternalEncryptBytes(byte[] buffer, int offset, int size, ContentType type) { // only accepts sizes of less than 16Kb; does not do any error checking
			byte[] bytes = new byte[size];
			Array.Copy(buffer, offset, bytes, 0, size);
			RecordMessage message = new RecordMessage(MessageType.PlainText, type, m_HandshakeLayer.GetVersion(), bytes);
			WrapMessage(message);
			return message.ToBytes();
		}
        }         //*/

        protected void UnwrapMessage(RecordMessage message)
        {
            if (message.length != message.fragment.Length)
            {
                throw new SslException(AlertDescription.IllegalParameter, "Message length is invalid.");
            }
            byte[] remoteMac   = null, decrypted = null, localMac = null;
            bool   cipherError = false;

            // decrypt and verify the message
            if (m_BulkDecryption != null)
            {
                if (message.length <= m_RemoteHasher.HashSize / 8)
                {
                    throw new SslException(AlertDescription.DecodeError, "Message is too small.");
                }
                if (message.length % m_BulkDecryption.OutputBlockSize != 0)
                {
                    throw new SslException(AlertDescription.DecryptError, "Message length is invalid.");
                }
                // decrypt the message
                if (m_BulkDecryption.OutputBlockSize == 1)                   // is stream cipher?
                {
                    decrypted = new byte[message.length];
                    m_BulkDecryption.TransformBlock(message.fragment, 0, message.length, decrypted, 0);
                    remoteMac = new byte[m_RemoteHasher.HashSize / 8];
                    Array.Copy(decrypted, message.length - remoteMac.Length, remoteMac, 0, remoteMac.Length);
                    message.fragment = new byte[decrypted.Length - remoteMac.Length];
                    Array.Copy(decrypted, 0, message.fragment, 0, message.fragment.Length);
                    message.length = (ushort)message.fragment.Length;
                }
                else                     // cipher is block cipher
                {
                    decrypted = new byte[message.fragment.Length];
                    m_BulkDecryption.TransformBlock(message.fragment, 0, decrypted.Length, decrypted, 0);
                    byte padding = decrypted[decrypted.Length - 1];
                    if (message.length < padding + m_RemoteHasher.HashSize / 8 + 1)
                    {
                        cipherError = true;
                        remoteMac   = new byte[m_RemoteHasher.HashSize / 8];
                    }
                    else
                    {
                        int realSize = (message.length - padding) - 1;
                        remoteMac = new byte[m_RemoteHasher.HashSize / 8];
                        Array.Copy(decrypted, realSize - remoteMac.Length, remoteMac, 0, remoteMac.Length);
                        message.fragment = new byte[realSize - remoteMac.Length];
                        Array.Copy(decrypted, 0, message.fragment, 0, message.fragment.Length);
                        message.length = (ushort)message.fragment.Length;
                        if (m_HandshakeLayer.GetProtocol() == SecureProtocol.Tls1)
                        {
                            // check padding
                            for (int i = realSize; i < decrypted.Length; i++)
                            {
                                if (decrypted[i] != padding)
                                {
                                    cipherError = true;
                                }
                            }
                        }
                    }
                }
                // calculate the MAC
                localMac = GetULongBytes(m_InputSequenceNumber);
                m_RemoteHasher.Initialize();
                m_RemoteHasher.TransformBlock(localMac, 0, localMac.Length, localMac, 0);                       // seq_num + ..
                localMac = message.ToBytes();
                if (m_HandshakeLayer.GetProtocol() == SecureProtocol.Tls1)
                {
                    m_RemoteHasher.TransformFinalBlock(localMac, 0, localMac.Length);                                   // .. + TLSCompressed.type + TLSCompressed.version + TLSCompressed.length + TLSCompressed.fragment
                }
                else if (m_HandshakeLayer.GetProtocol() == SecureProtocol.Ssl3)
                {
                    m_RemoteHasher.TransformBlock(localMac, 0, 1, localMac, 0);                     // type
                    m_RemoteHasher.TransformFinalBlock(localMac, 3, localMac.Length - 3);           // length + fragment
                }
                else
                {
                    throw new NotSupportedException("Only SSL3 and TLS1 are supported");
                }
                localMac = m_RemoteHasher.Hash;
                // compare MACs
                for (int i = 0; i < remoteMac.Length; i++)
                {
                    if (remoteMac[i] != localMac[i])
                    {
                        cipherError = true;
                    }
                }
                // throw cipher error, if necessary
                if (cipherError)
                {
                    throw new SslException(AlertDescription.BadRecordMac, "An error occurred during the decryption and verification process.");
                }
            }
            // decompress the message
            if (m_RemoteCompressor != null)
            {
                message.fragment = m_RemoteCompressor.Decompress(message.fragment);
                message.length   = (ushort)message.fragment.Length;
            }
            // final adjustments
            message.messageType = MessageType.PlainText;
            m_InputSequenceNumber++;
        }
 protected void WrapMessage(RecordMessage message)
 {
     if (message.length != message.fragment.Length)
     {
         throw new SslException(AlertDescription.IllegalParameter, "Message length is invalid.");
     }
     byte[] mac = null;
     try {
         // compress the message
         if (m_LocalCompressor != null)
         {
             message.fragment = m_LocalCompressor.Compress(message.fragment);
             message.length   = (ushort)message.fragment.Length;
         }
         // encrypt the message and MAC
         if (m_LocalHasher != null)
         {
             // calculate the MAC
             mac = GetULongBytes(m_OutputSequenceNumber);
             m_LocalHasher.Initialize();
             m_LocalHasher.TransformBlock(mac, 0, mac.Length, mac, 0);                           // seq_num + ..
             mac = message.ToBytes();
             if (m_HandshakeLayer.GetProtocol() == SecureProtocol.Tls1)
             {
                 m_LocalHasher.TransformFinalBlock(mac, 0, mac.Length);                                  // .. + TLSCompressed.type + TLSCompressed.version + TLSCompressed.length + TLSCompressed.fragment
             }
             else if (m_HandshakeLayer.GetProtocol() == SecureProtocol.Ssl3)
             {
                 m_LocalHasher.TransformBlock(mac, 0, 1, mac, 0);                         // type
                 m_LocalHasher.TransformFinalBlock(mac, 3, mac.Length - 3);               // length + fragment
             }
             else
             {
                 throw new NotSupportedException("Only SSL3 and TLS1 are supported");
             }
             mac = m_LocalHasher.Hash;
             // encrypt the message
             if (m_BulkEncryption.OutputBlockSize == 1)                       // is stream cipher?
             {
                 byte[] ret = new byte[message.length + mac.Length];
                 m_BulkEncryption.TransformBlock(message.fragment, 0, message.length, ret, 0);
                 m_BulkEncryption.TransformBlock(mac, 0, mac.Length, ret, message.length);
                 message.fragment = ret;
             }
             else                         // cipher is block cipher
             {
                 int    obs     = m_BulkEncryption.OutputBlockSize;
                 byte   padding = (byte)((obs - (message.length + mac.Length + 1) % obs) % obs);
                 byte[] ret     = new byte[message.length + mac.Length + padding + 1];
                 Array.Copy(message.fragment, 0, ret, 0, message.length);
                 Array.Copy(mac, 0, ret, message.length, mac.Length);
                 if (m_HandshakeLayer.GetProtocol() == SecureProtocol.Tls1)
                 {
                     for (int i = message.length + mac.Length; i < ret.Length; i++)
                     {
                         ret[i] = padding;
                     }
                 }
                 else
                 {
                     byte[] buffer = new byte[ret.Length - message.length - mac.Length];
                     m_HandshakeLayer.RNG.GetBytes(buffer);
                     Array.Copy(buffer, 0, ret, message.length + mac.Length, buffer.Length);
                     ret[ret.Length - 1] = padding;
                 }
                 m_BulkEncryption.TransformBlock(ret, 0, ret.Length, ret, 0);
                 message.fragment = ret;
             }
             message.length = (ushort)message.fragment.Length;
         }
     } catch (Exception e) {
         throw new SslException(e, AlertDescription.InternalError, "An exception occurred");
     }
     // final adjustments
     message.messageType = MessageType.Encrypted;
     m_OutputSequenceNumber++;
 }         //*/