Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
PemEncoding.cs
Go to the documentation of this file.
2
4
5public static class PemEncoding
6{
7 public static PemFields Find(ReadOnlySpan<char> pemData)
8 {
9 if (!TryFind(pemData, out var fields))
10 {
12 }
13 return fields;
14 }
15
16 public static bool TryFind(ReadOnlySpan<char> pemData, out PemFields fields)
17 {
18 if (pemData.Length < "-----BEGIN ".Length + "-----".Length * 2 + "-----END ".Length)
19 {
20 fields = default(PemFields);
21 return false;
22 }
23 Span<char> span = stackalloc char[256];
24 int num = 0;
25 int num2;
26 while ((num2 = pemData.IndexOfByOffset("-----BEGIN ", num)) >= 0)
27 {
28 int num3 = num2 + "-----BEGIN ".Length;
29 if (num2 > 0 && !IsWhiteSpaceCharacter(pemData[num2 - 1]))
30 {
31 num = num3;
32 continue;
33 }
34 int num4 = pemData.IndexOfByOffset("-----", num3);
35 if (num4 < 0)
36 {
37 fields = default(PemFields);
38 return false;
39 }
40 Range range = num3..num4;
41 ReadOnlySpan<char> readOnlySpan = pemData;
42 ReadOnlySpan<char> readOnlySpan2 = readOnlySpan[range];
43 if (IsValidLabel(readOnlySpan2))
44 {
45 int num5 = num4 + "-----".Length;
46 int num6 = "-----END ".Length + readOnlySpan2.Length + "-----".Length;
47 Span<char> destination2 = ((num6 > 256) ? ((Span<char>)new char[num6]) : span);
48 ReadOnlySpan<char> value = WritePostEB(readOnlySpan2, destination2);
49 int num7 = pemData.IndexOfByOffset(value, num5);
50 if (num7 >= 0)
51 {
52 int num8 = num7 + num6;
53 if (num8 >= pemData.Length - 1 || IsWhiteSpaceCharacter(pemData[num8]))
54 {
55 Range range2 = num5..num7;
56 readOnlySpan = pemData;
57 if (TryCountBase64(readOnlySpan[range2], out var base64Start, out var base64End, out var base64DecodedSize))
58 {
59 Range location = num2..num8;
60 Range base64data = (num5 + base64Start)..(num5 + base64End);
61 fields = new PemFields(range, base64data, location, base64DecodedSize);
62 return true;
63 }
64 }
65 }
66 }
67 if (num4 <= num)
68 {
69 fields = default(PemFields);
70 return false;
71 }
72 num = num4;
73 }
74 fields = default(PemFields);
75 return false;
77 {
78 int length = "-----END ".Length + label.Length + "-----".Length;
79 "-----END ".CopyTo(destination);
80 label.CopyTo(destination.Slice("-----END ".Length));
81 "-----".CopyTo(destination.Slice("-----END ".Length + label.Length));
82 return destination.Slice(0, length);
83 }
84 }
85
86 private static int IndexOfByOffset(this ReadOnlySpan<char> str, ReadOnlySpan<char> value, int startPosition)
87 {
88 int num = str.Slice(startPosition).IndexOf(value);
89 if (num != -1)
90 {
91 return num + startPosition;
92 }
93 return -1;
94 }
95
96 private static bool IsValidLabel(ReadOnlySpan<char> data)
97 {
98 if (data.IsEmpty)
99 {
100 return true;
101 }
102 bool flag = false;
103 for (int i = 0; i < data.Length; i++)
104 {
105 char c2 = data[i];
106 if (IsLabelChar(c2))
107 {
108 flag = true;
109 continue;
110 }
111 if ((c2 != ' ' && c2 != '-') || !flag)
112 {
113 return false;
114 }
115 flag = false;
116 }
117 return flag;
118 static bool IsLabelChar(char c)
119 {
120 if ((uint)(c - 33) <= 93u)
121 {
122 return c != '-';
123 }
124 return false;
125 }
126 }
127
128 private static bool TryCountBase64(ReadOnlySpan<char> str, out int base64Start, out int base64End, out int base64DecodedSize)
129 {
130 base64Start = 0;
131 base64End = str.Length;
132 if (str.IsEmpty)
133 {
134 base64DecodedSize = 0;
135 return true;
136 }
137 int num = 0;
138 int num2 = 0;
139 for (int i = 0; i < str.Length; i++)
140 {
141 char c = str[i];
143 {
144 if (num == 0)
145 {
146 base64Start++;
147 }
148 else
149 {
150 base64End--;
151 }
152 continue;
153 }
154 base64End = str.Length;
155 if (c == '=')
156 {
157 num2++;
158 continue;
159 }
160 if (num2 == 0 && IsBase64Character(c))
161 {
162 num++;
163 continue;
164 }
165 base64DecodedSize = 0;
166 return false;
167 }
168 int num3 = num2 + num;
169 if (num2 > 2 || ((uint)num3 & 3u) != 0)
170 {
171 base64DecodedSize = 0;
172 return false;
173 }
174 base64DecodedSize = (num3 >> 2) * 3 - num2;
175 return true;
176 }
177
178 [MethodImpl(MethodImplOptions.AggressiveInlining)]
179 private static bool IsBase64Character(char ch)
180 {
181 if (ch != '+' && ch != '/' && (uint)(ch - 48) >= 10u && (uint)(ch - 65) >= 26u)
182 {
183 return (uint)(ch - 97) < 26u;
184 }
185 return true;
186 }
187
188 [MethodImpl(MethodImplOptions.AggressiveInlining)]
189 private static bool IsWhiteSpaceCharacter(char ch)
190 {
191 if (ch != ' ' && ch != '\t' && ch != '\n')
192 {
193 return ch == '\r';
194 }
195 return true;
196 }
197
198 public static int GetEncodedSize(int labelLength, int dataLength)
199 {
200 if (labelLength < 0)
201 {
203 }
204 if (dataLength < 0)
205 {
207 }
208 if (labelLength > 1073741808)
209 {
211 }
212 if (dataLength > 1585834053)
213 {
215 }
216 int num = "-----BEGIN ".Length + labelLength + "-----".Length;
217 int num2 = "-----END ".Length + labelLength + "-----".Length;
218 int num3 = num + num2 + 1;
219 int num4 = (dataLength + 2) / 3 << 2;
220 int result;
221 int num5 = Math.DivRem(num4, 64, out result);
222 if (result > 0)
223 {
224 num5++;
225 }
226 int num6 = num4 + num5;
227 if (int.MaxValue - num6 < num3)
228 {
230 }
231 return num6 + num3;
232 }
233
234 public static bool TryWrite(ReadOnlySpan<char> label, ReadOnlySpan<byte> data, Span<char> destination, out int charsWritten)
235 {
236 if (!IsValidLabel(label))
237 {
239 }
240 int encodedSize = GetEncodedSize(label.Length, data.Length);
241 if (destination.Length < encodedSize)
242 {
243 charsWritten = 0;
244 return false;
245 }
246 charsWritten = 0;
247 charsWritten += Write("-----BEGIN ", destination, charsWritten);
248 charsWritten += Write(label, destination, charsWritten);
249 charsWritten += Write("-----", destination, charsWritten);
250 charsWritten += Write("\n", destination, charsWritten);
251 ReadOnlySpan<byte> bytes2 = data;
252 while (bytes2.Length >= 48)
253 {
254 charsWritten += WriteBase64(bytes2.Slice(0, 48), destination, charsWritten);
255 charsWritten += Write("\n", destination, charsWritten);
256 bytes2 = bytes2.Slice(48);
257 }
258 if (bytes2.Length > 0)
259 {
260 charsWritten += WriteBase64(bytes2, destination, charsWritten);
261 charsWritten += Write("\n", destination, charsWritten);
262 bytes2 = default(ReadOnlySpan<byte>);
263 }
264 charsWritten += Write("-----END ", destination, charsWritten);
265 charsWritten += Write(label, destination, charsWritten);
266 charsWritten += Write("-----", destination, charsWritten);
267 return true;
268 static int Write(ReadOnlySpan<char> str, Span<char> dest, int offset)
269 {
270 str.CopyTo(dest.Slice(offset));
271 return str.Length;
272 }
273 static int WriteBase64(ReadOnlySpan<byte> bytes, Span<char> dest, int offset)
274 {
275 if (!Convert.TryToBase64Chars(bytes, dest.Slice(offset), out var charsWritten2))
276 {
277 throw new ArgumentException(null, "destination");
278 }
279 return charsWritten2;
280 }
281 }
282
283 public static char[] Write(ReadOnlySpan<char> label, ReadOnlySpan<byte> data)
284 {
285 if (!IsValidLabel(label))
286 {
288 }
289 int encodedSize = GetEncodedSize(label.Length, data.Length);
290 char[] array = new char[encodedSize];
291 if (!TryWrite(label, data, array, out var _))
292 {
293 throw new ArgumentException(null, "data");
294 }
295 return array;
296 }
297}
static unsafe bool TryToBase64Chars(ReadOnlySpan< byte > bytes, Span< char > chars, out int charsWritten, Base64FormattingOptions options=Base64FormattingOptions.None)
Definition Convert.cs:2799
static int DivRem(int a, int b, out int result)
Definition Math.cs:329
static string Argument_PemEncoding_InvalidLabel
Definition SR.cs:32
static string Argument_PemEncoding_EncodedSizeTooLarge
Definition SR.cs:34
static string Argument_PemEncoding_NoPemFound
Definition SR.cs:30
static string ArgumentOutOfRange_NeedPositiveNumber
Definition SR.cs:56
Definition SR.cs:7
static bool IsValidLabel(ReadOnlySpan< char > data)
static PemFields Find(ReadOnlySpan< char > pemData)
Definition PemEncoding.cs:7
static bool TryCountBase64(ReadOnlySpan< char > str, out int base64Start, out int base64End, out int base64DecodedSize)
static bool TryFind(ReadOnlySpan< char > pemData, out PemFields fields)
static int IndexOfByOffset(this ReadOnlySpan< char > str, ReadOnlySpan< char > value, int startPosition)
static char[] Write(ReadOnlySpan< char > label, ReadOnlySpan< byte > data)
static bool TryWrite(ReadOnlySpan< char > label, ReadOnlySpan< byte > data, Span< char > destination, out int charsWritten)
static int GetEncodedSize(int labelLength, int dataLength)
void CopyTo(Span< T > destination)
ReadOnlySpan< T > Slice(int start)
Span< T > Slice(int start)
Definition Span.cs:271