~ubuntu-branches/ubuntu/trusty/keepass2/trusty-proposed

« back to all changes in this revision

Viewing changes to KeePassLib/Security/XorredBuffer.cs

  • Committer: Package Import Robot
  • Author(s): Julian Taylor
  • Date: 2011-12-30 15:45:59 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20111230154559-3en1b9v90hswvs1w
Tags: 2.18+dfsg-1
* New upstream release
  - refresh patches
  - drop upstream applied patches:
    explicitly-PUT-for-webdav-writes.patch
    prefer-4.0-framework-if-available.patch
* add patch to improve autotype when dealing with multiple keyboard layouts
  - Thanks to amiryal for the patch
* disable initial autoupdate popup via patch
* update years in debian/copyright

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
  KeePass Password Safe - The Open-Source Password Manager
3
 
  Copyright (C) 2003-2011 Dominik Reichl <dominik.reichl@t-online.de>
 
3
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
4
4
 
5
5
  This program is free software; you can redistribute it and/or modify
6
6
  it under the terms of the GNU General Public License as published by
24
24
{
25
25
        /// <summary>
26
26
        /// Represents an object that is encrypted using a XOR pad until
27
 
        /// it is read. The key XOR pad can be changed without revealing the
28
 
        /// protected data in process memory.
 
27
        /// it is read. <c>XorredBuffer</c> objects are immutable and
 
28
        /// thread-safe.
29
29
        /// </summary>
30
30
        public sealed class XorredBuffer
31
31
        {
32
 
                private byte[] m_pbData = new byte[0]; // Never null
33
 
                private byte[] m_pbXorPad = new byte[0]; // Never null
 
32
                private byte[] m_pbData; // Never null
 
33
                private byte[] m_pbXorPad; // Always valid for m_pbData
34
34
 
35
35
                /// <summary>
36
36
                /// Length of the protected data in bytes.
45
45
                /// and a XOR pad that decrypts the protected data. The
46
46
                /// <paramref name="pbProtectedData" /> byte array must have the same size
47
47
                /// as the <paramref name="pbXorPad" /> byte array.
 
48
                /// The <c>XorredBuffer</c> object takes ownership of the two byte
 
49
                /// arrays, i.e. the caller must not use or modify them afterwards.
48
50
                /// </summary>
49
51
                /// <param name="pbProtectedData">Protected data (XOR pad applied).</param>
50
 
                /// <param name="pbXorPad">XOR pad that is used to decrypt the
51
 
                /// <paramref name="pbData" /> parameter.</param>
 
52
                /// <param name="pbXorPad">XOR pad that can be used to decrypt the
 
53
                /// <paramref name="pbProtectedData" /> parameter.</param>
52
54
                /// <exception cref="System.ArgumentNullException">Thrown if one of the input
53
55
                /// parameters is <c>null</c>.</exception>
54
56
                /// <exception cref="System.ArgumentException">Thrown if the byte arrays are
55
57
                /// of different size.</exception>
56
58
                public XorredBuffer(byte[] pbProtectedData, byte[] pbXorPad)
57
59
                {
58
 
                        Debug.Assert(pbProtectedData != null); if(pbProtectedData == null) throw new ArgumentNullException("pbProtectedData");
59
 
                        Debug.Assert(pbXorPad != null); if(pbXorPad == null) throw new ArgumentNullException("pbXorPad");
 
60
                        if(pbProtectedData == null) { Debug.Assert(false); throw new ArgumentNullException("pbProtectedData"); }
 
61
                        if(pbXorPad == null) { Debug.Assert(false); throw new ArgumentNullException("pbXorPad"); }
60
62
 
61
63
                        Debug.Assert(pbProtectedData.Length == pbXorPad.Length);
62
64
                        if(pbProtectedData.Length != pbXorPad.Length) throw new ArgumentException();
65
67
                        m_pbXorPad = pbXorPad;
66
68
                }
67
69
 
68
 
                private void Decrypt()
69
 
                {
70
 
                        Debug.Assert((m_pbData.Length == m_pbXorPad.Length) || (m_pbXorPad.Length == 0));
71
 
 
72
 
                        if(m_pbData.Length == m_pbXorPad.Length)
73
 
                        {
74
 
                                for(int i = 0; i < m_pbData.Length; ++i)
75
 
                                        m_pbData[i] ^= m_pbXorPad[i];
76
 
 
77
 
                                m_pbXorPad = new byte[0];
78
 
                        }
79
 
                }
80
 
 
81
70
                /// <summary>
82
 
                /// Decrypt the buffer. The <c>XorredBuffer</c> protection is useless
83
 
                /// after you used this method. The object cannot be re-encrypted.
 
71
                /// Get a copy of the plain-text. The caller is responsible
 
72
                /// for clearing the byte array safely after using it.
84
73
                /// </summary>
85
74
                /// <returns>Unprotected plain-text byte array.</returns>
86
75
                public byte[] ReadPlainText()
87
76
                {
88
 
                        Decrypt();
89
 
                        return m_pbData;
90
 
                }
91
 
 
92
 
                /// <summary>
93
 
                /// Change the protection key for this <c>XorredBuffer</c> object.
94
 
                /// The data will first be decrypted using the old key and then
95
 
                /// re-encrypted using the new key. This operation doesn't reveal
96
 
                /// the plain-text in the process memory.
97
 
                /// </summary>
98
 
                /// <param name="pbNewXorPad">New protection pad. Must contain exactly
99
 
                /// the same number of bytes as the length of the currently protected data.
100
 
                /// Use the <c>Length</c> property of the <c>XorredBuffer</c> to query
101
 
                /// the data length and pass a correct number of bytes to <c>ChangeKey</c>.</param>
102
 
                /// <returns>New protected data (encrypted using the new XOR pad).</returns>
103
 
                /// <exception cref="System.ArgumentNullException">Thrown if the input
104
 
                /// parameter is <c>null</c>.</exception>
105
 
                /// <exception cref="System.ArgumentException">Thrown if the input
106
 
                /// byte array doesn't have the correct size.</exception>
107
 
                public byte[] ChangeKey(byte[] pbNewXorPad)
108
 
                {
109
 
                        Debug.Assert(pbNewXorPad != null); if(pbNewXorPad == null) throw new ArgumentNullException("pbNewXorPad");
110
 
 
111
 
                        Debug.Assert(pbNewXorPad.Length == m_pbData.Length);
112
 
                        if(pbNewXorPad.Length != m_pbData.Length) throw new ArgumentException();
113
 
 
114
 
                        if(m_pbXorPad.Length == m_pbData.Length) // Data is protected
115
 
                        {
116
 
                                for(int i = 0; i < m_pbData.Length; ++i)
117
 
                                        m_pbData[i] ^= (byte)(m_pbXorPad[i] ^ pbNewXorPad[i]);
118
 
                        }
119
 
                        else // Data is unprotected
120
 
                        {
121
 
                                for(int i = 0; i < m_pbData.Length; ++i)
122
 
                                        m_pbData[i] ^= pbNewXorPad[i];
123
 
                        }
124
 
 
125
 
                        m_pbXorPad = pbNewXorPad;
126
 
                        return m_pbData;
127
 
                }
128
 
 
129
 
                public bool EqualsValue(XorredBuffer xb)
 
77
                        byte[] pbPlain = new byte[m_pbData.Length];
 
78
 
 
79
                        for(int i = 0; i < pbPlain.Length; ++i)
 
80
                                pbPlain[i] = (byte)(m_pbData[i] ^ m_pbXorPad[i]);
 
81
 
 
82
                        return pbPlain;
 
83
                }
 
84
 
 
85
                /* public bool EqualsValue(XorredBuffer xb)
130
86
                {
131
87
                        if(xb == null) { Debug.Assert(false); throw new ArgumentNullException("xb"); }
132
88
 
133
89
                        if(xb.m_pbData.Length != m_pbData.Length) return false;
134
90
 
135
 
                        bool bDecThis = (m_pbData.Length == m_pbXorPad.Length);
136
 
                        bool bDecOther = (xb.m_pbData.Length == xb.m_pbXorPad.Length);
137
91
                        for(int i = 0; i < m_pbData.Length; ++i)
138
92
                        {
139
 
                                byte bt1 = m_pbData[i];
140
 
                                if(bDecThis) bt1 ^= m_pbXorPad[i];
141
 
 
142
 
                                byte bt2 = xb.m_pbData[i];
143
 
                                if(bDecOther) bt2 ^= xb.m_pbXorPad[i];
 
93
                                byte bt1 = (byte)(m_pbData[i] ^ m_pbXorPad[i]);
 
94
                                byte bt2 = (byte)(xb.m_pbData[i] ^ xb.m_pbXorPad[i]);
144
95
 
145
96
                                if(bt1 != bt2) return false;
146
97
                        }
154
105
 
155
106
                        if(pb.Length != m_pbData.Length) return false;
156
107
 
157
 
                        if(m_pbData.Length == m_pbXorPad.Length)
158
 
                        {
159
 
                                for(int i = 0; i < m_pbData.Length; ++i)
160
 
                                {
161
 
                                        if((byte)(m_pbData[i] ^ m_pbXorPad[i]) != pb[i]) return false;
162
 
                                }
163
 
                                return true;
164
 
                        }
165
 
 
166
108
                        for(int i = 0; i < m_pbData.Length; ++i)
167
109
                        {
168
 
                                if(m_pbData[i] != pb[i]) return false;
 
110
                                if((byte)(m_pbData[i] ^ m_pbXorPad[i]) != pb[i]) return false;
169
111
                        }
 
112
 
170
113
                        return true;
171
 
                }
172
 
 
173
 
                /// <summary>
174
 
                /// XOR all bytes in a data buffer with a pad. Both byte arrays must
175
 
                /// be of the same size.
176
 
                /// </summary>
177
 
                /// <param name="pbData">Data to be protected.</param>
178
 
                /// <param name="pbPad">XOR pad.</param>
179
 
                /// <exception cref="System.ArgumentNullException">Thrown if one of the
180
 
                /// parameters is <c>null</c>.</exception>
181
 
                /// <exception cref="System.ArgumentException">Thrown if the length of
182
 
                /// the data array and the pad aren't equal.</exception>
183
 
                [Obsolete("Use MemUtil.XorArray instead.")]
184
 
                public static void XorArrays(byte[] pbData, byte[] pbPad)
185
 
                {
186
 
                        Debug.Assert(pbData != null); if(pbData == null) throw new ArgumentNullException("pbData");
187
 
                        Debug.Assert(pbPad != null); if(pbPad == null) throw new ArgumentNullException("pbPad");
188
 
                        
189
 
                        Debug.Assert(pbData.Length == pbPad.Length);
190
 
                        if(pbData.Length != pbPad.Length) throw new ArgumentException();
191
 
 
192
 
                        for(int i = 0; i < pbData.Length; ++i)
193
 
                                pbData[i] ^= pbPad[i];
194
 
                }
 
114
                } */
195
115
        }
196
116
}