Commit 412b7e76 412b7e760ed285384ac2d677311e1fe7de8999c4 by Christian Gerdes

Merge branch 'master' into 'master'

PEM support in Client Certificate

Added PEM format support for certificate files by using the Bouncy Castle API version 1.8.1

See merge request !1
2 parents 7d536c29 70bac17f
Showing 1000 changed files with 4889 additions and 2 deletions

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

TestResults
\ No newline at end of file
......@@ -8,6 +8,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
LICENSE = LICENSE
LIL_VSTT_Plugins.vsmdi = LIL_VSTT_Plugins.vsmdi
Local.testsettings = Local.testsettings
Notes.md = Notes.md
README.md = README.md
EndProjectSection
EndProject
......
using System;
/************************************************************************************************
* All code in this file is under the MS-RL License (https://opensource.org/licenses/MS-RL) *
* By using the code in this file in any way, you agree to the above license terms. *
* Copyright (C) LIGHTS IN LINE AB (https://www.lightsinline.se) *
* Repository, Wiki, Issue tracker and more at https://git.lightsinline.se/products/VSTT-Plugins *
* *
* Contributors *
* LIGHTS IN LINE AB *
* SWEDBANK AB *
* SKATTEVERKET *
************************************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* This package is based on the work done by Keiron Liddle, Aftex Software
* <keiron@aftexsw.com> to whom the Ant project is very grateful for his
* great code.
*/
using System;
namespace Org.BouncyCastle.Apache.Bzip2
{
/**
* Base class for both the compress and decompress classes.
* Holds common arrays, and static data.
*
* @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
*/
public class BZip2Constants {
public const int baseBlockSize = 100000;
public const int MAX_ALPHA_SIZE = 258;
public const int MAX_CODE_LEN = 23;
public const int RUNA = 0;
public const int RUNB = 1;
public const int N_GROUPS = 6;
public const int G_SIZE = 50;
public const int N_ITERS = 4;
public const int MAX_SELECTORS = (2 + (900000 / G_SIZE));
public const int NUM_OVERSHOOT_BYTES = 20;
public static readonly int[] rNums = {
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
936, 638
};
}
}
\ No newline at end of file
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* This package is based on the work done by Keiron Liddle), Aftex Software
* <keiron@aftexsw.com> to whom the Ant project is very grateful for his
* great code.
*/
using System;
namespace Org.BouncyCastle.Apache.Bzip2
{
/**
* A simple class the hold and calculate the CRC for sanity checking
* of the data.
*
* @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
*/
internal class CRC
{
public static readonly int[] crc32Table = {
unchecked((int)0x00000000), unchecked((int)0x04c11db7), unchecked((int)0x09823b6e), unchecked((int)0x0d4326d9),
unchecked((int)0x130476dc), unchecked((int)0x17c56b6b), unchecked((int)0x1a864db2), unchecked((int)0x1e475005),
unchecked((int)0x2608edb8), unchecked((int)0x22c9f00f), unchecked((int)0x2f8ad6d6), unchecked((int)0x2b4bcb61),
unchecked((int)0x350c9b64), unchecked((int)0x31cd86d3), unchecked((int)0x3c8ea00a), unchecked((int)0x384fbdbd),
unchecked((int)0x4c11db70), unchecked((int)0x48d0c6c7), unchecked((int)0x4593e01e), unchecked((int)0x4152fda9),
unchecked((int)0x5f15adac), unchecked((int)0x5bd4b01b), unchecked((int)0x569796c2), unchecked((int)0x52568b75),
unchecked((int)0x6a1936c8), unchecked((int)0x6ed82b7f), unchecked((int)0x639b0da6), unchecked((int)0x675a1011),
unchecked((int)0x791d4014), unchecked((int)0x7ddc5da3), unchecked((int)0x709f7b7a), unchecked((int)0x745e66cd),
unchecked((int)0x9823b6e0), unchecked((int)0x9ce2ab57), unchecked((int)0x91a18d8e), unchecked((int)0x95609039),
unchecked((int)0x8b27c03c), unchecked((int)0x8fe6dd8b), unchecked((int)0x82a5fb52), unchecked((int)0x8664e6e5),
unchecked((int)0xbe2b5b58), unchecked((int)0xbaea46ef), unchecked((int)0xb7a96036), unchecked((int)0xb3687d81),
unchecked((int)0xad2f2d84), unchecked((int)0xa9ee3033), unchecked((int)0xa4ad16ea), unchecked((int)0xa06c0b5d),
unchecked((int)0xd4326d90), unchecked((int)0xd0f37027), unchecked((int)0xddb056fe), unchecked((int)0xd9714b49),
unchecked((int)0xc7361b4c), unchecked((int)0xc3f706fb), unchecked((int)0xceb42022), unchecked((int)0xca753d95),
unchecked((int)0xf23a8028), unchecked((int)0xf6fb9d9f), unchecked((int)0xfbb8bb46), unchecked((int)0xff79a6f1),
unchecked((int)0xe13ef6f4), unchecked((int)0xe5ffeb43), unchecked((int)0xe8bccd9a), unchecked((int)0xec7dd02d),
unchecked((int)0x34867077), unchecked((int)0x30476dc0), unchecked((int)0x3d044b19), unchecked((int)0x39c556ae),
unchecked((int)0x278206ab), unchecked((int)0x23431b1c), unchecked((int)0x2e003dc5), unchecked((int)0x2ac12072),
unchecked((int)0x128e9dcf), unchecked((int)0x164f8078), unchecked((int)0x1b0ca6a1), unchecked((int)0x1fcdbb16),
unchecked((int)0x018aeb13), unchecked((int)0x054bf6a4), unchecked((int)0x0808d07d), unchecked((int)0x0cc9cdca),
unchecked((int)0x7897ab07), unchecked((int)0x7c56b6b0), unchecked((int)0x71159069), unchecked((int)0x75d48dde),
unchecked((int)0x6b93dddb), unchecked((int)0x6f52c06c), unchecked((int)0x6211e6b5), unchecked((int)0x66d0fb02),
unchecked((int)0x5e9f46bf), unchecked((int)0x5a5e5b08), unchecked((int)0x571d7dd1), unchecked((int)0x53dc6066),
unchecked((int)0x4d9b3063), unchecked((int)0x495a2dd4), unchecked((int)0x44190b0d), unchecked((int)0x40d816ba),
unchecked((int)0xaca5c697), unchecked((int)0xa864db20), unchecked((int)0xa527fdf9), unchecked((int)0xa1e6e04e),
unchecked((int)0xbfa1b04b), unchecked((int)0xbb60adfc), unchecked((int)0xb6238b25), unchecked((int)0xb2e29692),
unchecked((int)0x8aad2b2f), unchecked((int)0x8e6c3698), unchecked((int)0x832f1041), unchecked((int)0x87ee0df6),
unchecked((int)0x99a95df3), unchecked((int)0x9d684044), unchecked((int)0x902b669d), unchecked((int)0x94ea7b2a),
unchecked((int)0xe0b41de7), unchecked((int)0xe4750050), unchecked((int)0xe9362689), unchecked((int)0xedf73b3e),
unchecked((int)0xf3b06b3b), unchecked((int)0xf771768c), unchecked((int)0xfa325055), unchecked((int)0xfef34de2),
unchecked((int)0xc6bcf05f), unchecked((int)0xc27dede8), unchecked((int)0xcf3ecb31), unchecked((int)0xcbffd686),
unchecked((int)0xd5b88683), unchecked((int)0xd1799b34), unchecked((int)0xdc3abded), unchecked((int)0xd8fba05a),
unchecked((int)0x690ce0ee), unchecked((int)0x6dcdfd59), unchecked((int)0x608edb80), unchecked((int)0x644fc637),
unchecked((int)0x7a089632), unchecked((int)0x7ec98b85), unchecked((int)0x738aad5c), unchecked((int)0x774bb0eb),
unchecked((int)0x4f040d56), unchecked((int)0x4bc510e1), unchecked((int)0x46863638), unchecked((int)0x42472b8f),
unchecked((int)0x5c007b8a), unchecked((int)0x58c1663d), unchecked((int)0x558240e4), unchecked((int)0x51435d53),
unchecked((int)0x251d3b9e), unchecked((int)0x21dc2629), unchecked((int)0x2c9f00f0), unchecked((int)0x285e1d47),
unchecked((int)0x36194d42), unchecked((int)0x32d850f5), unchecked((int)0x3f9b762c), unchecked((int)0x3b5a6b9b),
unchecked((int)0x0315d626), unchecked((int)0x07d4cb91), unchecked((int)0x0a97ed48), unchecked((int)0x0e56f0ff),
unchecked((int)0x1011a0fa), unchecked((int)0x14d0bd4d), unchecked((int)0x19939b94), unchecked((int)0x1d528623),
unchecked((int)0xf12f560e), unchecked((int)0xf5ee4bb9), unchecked((int)0xf8ad6d60), unchecked((int)0xfc6c70d7),
unchecked((int)0xe22b20d2), unchecked((int)0xe6ea3d65), unchecked((int)0xeba91bbc), unchecked((int)0xef68060b),
unchecked((int)0xd727bbb6), unchecked((int)0xd3e6a601), unchecked((int)0xdea580d8), unchecked((int)0xda649d6f),
unchecked((int)0xc423cd6a), unchecked((int)0xc0e2d0dd), unchecked((int)0xcda1f604), unchecked((int)0xc960ebb3),
unchecked((int)0xbd3e8d7e), unchecked((int)0xb9ff90c9), unchecked((int)0xb4bcb610), unchecked((int)0xb07daba7),
unchecked((int)0xae3afba2), unchecked((int)0xaafbe615), unchecked((int)0xa7b8c0cc), unchecked((int)0xa379dd7b),
unchecked((int)0x9b3660c6), unchecked((int)0x9ff77d71), unchecked((int)0x92b45ba8), unchecked((int)0x9675461f),
unchecked((int)0x8832161a), unchecked((int)0x8cf30bad), unchecked((int)0x81b02d74), unchecked((int)0x857130c3),
unchecked((int)0x5d8a9099), unchecked((int)0x594b8d2e), unchecked((int)0x5408abf7), unchecked((int)0x50c9b640),
unchecked((int)0x4e8ee645), unchecked((int)0x4a4ffbf2), unchecked((int)0x470cdd2b), unchecked((int)0x43cdc09c),
unchecked((int)0x7b827d21), unchecked((int)0x7f436096), unchecked((int)0x7200464f), unchecked((int)0x76c15bf8),
unchecked((int)0x68860bfd), unchecked((int)0x6c47164a), unchecked((int)0x61043093), unchecked((int)0x65c52d24),
unchecked((int)0x119b4be9), unchecked((int)0x155a565e), unchecked((int)0x18197087), unchecked((int)0x1cd86d30),
unchecked((int)0x029f3d35), unchecked((int)0x065e2082), unchecked((int)0x0b1d065b), unchecked((int)0x0fdc1bec),
unchecked((int)0x3793a651), unchecked((int)0x3352bbe6), unchecked((int)0x3e119d3f), unchecked((int)0x3ad08088),
unchecked((int)0x2497d08d), unchecked((int)0x2056cd3a), unchecked((int)0x2d15ebe3), unchecked((int)0x29d4f654),
unchecked((int)0xc5a92679), unchecked((int)0xc1683bce), unchecked((int)0xcc2b1d17), unchecked((int)0xc8ea00a0),
unchecked((int)0xd6ad50a5), unchecked((int)0xd26c4d12), unchecked((int)0xdf2f6bcb), unchecked((int)0xdbee767c),
unchecked((int)0xe3a1cbc1), unchecked((int)0xe760d676), unchecked((int)0xea23f0af), unchecked((int)0xeee2ed18),
unchecked((int)0xf0a5bd1d), unchecked((int)0xf464a0aa), unchecked((int)0xf9278673), unchecked((int)0xfde69bc4),
unchecked((int)0x89b8fd09), unchecked((int)0x8d79e0be), unchecked((int)0x803ac667), unchecked((int)0x84fbdbd0),
unchecked((int)0x9abc8bd5), unchecked((int)0x9e7d9662), unchecked((int)0x933eb0bb), unchecked((int)0x97ffad0c),
unchecked((int)0xafb010b1), unchecked((int)0xab710d06), unchecked((int)0xa6322bdf), unchecked((int)0xa2f33668),
unchecked((int)0xbcb4666d), unchecked((int)0xb8757bda), unchecked((int)0xb5365d03), unchecked((int)0xb1f740b4)
};
public CRC() {
InitialiseCRC();
}
internal void InitialiseCRC() {
globalCrc = unchecked((int)0xffffffff);
}
internal int GetFinalCRC() {
return ~globalCrc;
}
internal int GetGlobalCRC() {
return globalCrc;
}
internal void SetGlobalCRC(int newCrc) {
globalCrc = newCrc;
}
internal void UpdateCRC(int inCh) {
int temp = (globalCrc >> 24) ^ inCh;
if (temp < 0) {
temp = 256 + temp;
}
globalCrc = (globalCrc << 8) ^ CRC.crc32Table[temp];
}
internal int globalCrc;
}
}
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
<title>Contributors</title>
</head>
<body>
<h2>The Bouncy Castle Cryptographic C#&reg; API</h2>
<p>
<h3>Donors</h3>
<p>
The following people and organisations donated financially to help with the release of 1.8:
<br />&nbsp;<br />
Andrew Grosser, Antonio Royo, dmitry.ribakov&#64gmail.com, PhreePhly, and encryptomatic.com.
</p>
<h3>Code Contributors:</h3>
<p>The following people have contributed to the C# Bouncy Castle Cryptography
Package.</p>
<p>Thanks, may your castles never deflate!</p>
<ul>
<li>
<p>Kaiser Yang &lt;kaiseryang&#064yahoo.com&gt; - initial port of the lightweight
API and ASN.1 library. Finding BigInteger loop problem.</p>
</li>
<li>
<p>Asier Murciego &lt;a.murciego&#064captiva-sys.es&gt; - Further patching to
BigInteger library.</p>
</li>
<li>
<p>Megan Woods &lt;megan.woods&#064widestreet.com.au&gt; - X509 certificate
generation, RSA/DSA digest signature classes.</p>
</li>
<li>
<p>David Del Vecchio &lt;ddelvecc&#064virginia.edu&gt; - patches to RSA Pkcs1
Signature generation OID issues, help with clarifications on DateTime and
certificates.</p>
</li>
<li>
<p>Nelson Fernandez &lt;nelson-bc&#064kpanic.com.ar&gt; - patches to allow
compilation under mono.</p>
</li>
<li>
<p>Paulo Soares &lt;psoares&#064consiste.pt&gt; - patches to X509CertificateParser,
C# port of JZlib plus inflater/deflater streams, C# port of Apache BZip2
classes.</p>
</li>
<li>
<p>Pawel Niewiadomski &lt;11110000b&#064gmail.com&gt; - patches for X509 and CMS,
unit test for time classes.</p>
</li>
<li>
<p>Jesper Johansen &lt;jesper&#064hc.jay.net&gt; - bug fix for DerT61String
encodings.</p>
</li>
<li>
<p>Adam Sternberg &lt;agsternberg&#064gmail.com&gt; - identified problem with
generation of PGP public keyrings.</p>
</li>
<li>
<p>Kirill Zhuklinets &lt;zhuklinets_k&#064gaz-is.ru&gt; - initial submission of
bulk of Asn1.Esf classes (RFC 3126).</p>
</li>
<li>
<p>Dr Andrew Gray &lt;andrew.gray&#064rcrt.co.uk&gt; - identified problem with
BigInteger.ModPow for negative exponents.</p>
</li>
<li>
<p>Mauricio Ulate &lt;mulate&#064gmail.com&gt; - identified problem with non-ASCII
pass phrases in PGP.</p>
</li>
<li>
<p>John Allberg &lt;John.Allberg&#064teliasonera.com&gt; - initial implementation
of CryptoApiRandomGenerator.</p>
</li>
<li>
<p>Mattias &Ouml;hrn &lt;mattias.ohrn&#064gmail.com&gt; - identified problem with
Pkcs12Store.Save and provided fix.</p>
</li>
<li>
<p>Jen Andre &lt;jandre&#064gmail.com&gt; - initial implementation of
case-insensitive searches for PGP keyrings.</p>
</li>
<li>
<p>#Cyrille37# &lt;cyrille37&#064gmail.com&gt; - identified problem with
BigInteger.ModInverse for negative values.</p>
</li>
<li>
<p>David Reis Jr &lt;davidreis&#064yahoo.com&gt; - bug fix for X509CrlStoreSelector
handling of NextUpdate, fix handling of null parameters for DSA in key
factories, initial port of Pkix namespace and supporting tests.
</p>
</li>
<li>
<p>Ivan Peev &lt;ivan.peev&#064cozyroc.com&gt; - bug fix for version string
displayed in PGP armored output.</p>
</li>
<li>
<p>Hector Ornelas Aciga &lt;hector.ornelas&#064sat.gob.mx&gt; - patch to add support for PKCS#5 Scheme 2 keys.</p>
</li>
<li>
<p>Tom Van Holle &lt;tvh&#064dsoft.be&gt; - patch to add new class: Pkcs10CertificationRequestDelaySigned.</p>
</li>
<li>
<p>Kalev Lember &lt;kalev&#064smartlink.ee&gt; - patch to fix compilation problem under Mono 2.8+.</p>
</li>
<li>
<p>Kyle Hamilton &lt;kyanha.bouncycastle&#064kyanha.net&gt; - identified problem with BigInteger.Multiply, patch for MiscPemGenerator infinite recursion,
proposed improvements in use of random numbers.</p>
</li>
<li>
<p>Atanas Krachev &lt;akrachev&#064gmail.com&gt; - added support for revocation signatures in OpenPGP.</p>
</li>
<li>
<p>Torsten Moschny &lt;t.moschny&#064web.de&gt; - identified problem where PrivateKeyFactory/PublicKeyFactory failed to preserve publicKeyParamSet for EC keys.</p>
</li>
<li>
<p>Thomas Heggelund &lt;the&#064dips.no&gt; - identified problem with RSAParameters fields requiring zero-byte padding to satisfy .NET.</p>
</li>
<li>
<p>Laszlo Magyar &lt;lmagyar1973&#064gmail.com&gt; - patch to fix problem with SubjectDirectoryAttributes constructor.</p>
</li>
<li>
<p>Tim Whittington (https://github.com/timw) - ports of ChaCha, GMAC, Memoable, Poly1305, Skein, SM3, Threefish, XSalsa20. Registerised Salsa20 core.</p>
</li>
<li>
<p>Oscar Jacobsson (https://github.com/OscarAyoy) - patch to fix DerEnumerated constructor (including test coverage).</p>
</li>
<li>
<p>Michael Krueger &lt;michael.krueger&#064secardeo.com&gt; - patch to fix Asn1.Cmp.RevDetails constructor.</p>
</li>
<li>
<p>Daniel Nauck &lt;daniel.nauck&#064gmail.com&gt; - patch for Portable Class Library support.</p>
</li>
<li>
<p>John Allberg &lt;john&#064ayoy.se&gt; - improvements to Portable Class Library patch.</p>
</li>
<li>
<p>Oren Novotny (https://github.com/onovotny) - developed and maintained a fork supporting Portable Class Library, worked closely with us to integrate the changes back into the main project.</p>
</li>
<li>
<p>Nicolas Dorier (https://github.com/NicolasDorier) - patch to fix culture-dependent lookups in MacUtilities.
</li>
</ul>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="content-type">
<title>License</title>
</head>
<body>
<h2>The Bouncy Castle Cryptographic C#&reg; API</h2>
<h3>License:</h3>
The Bouncy Castle License<br>
Copyright (c) 2000-2015 The Legion of the Bouncy Castle Inc.
(http://www.bouncycastle.org)<br>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights to use, copy, modify, merge,
publish, distribute, sub license, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:<br>
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.<br>
<span style="font-weight: bold;">THE SOFTWARE IS PROVIDED "AS IS",
WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER</span><br
style="font-weight: bold;">
<span style="font-weight: bold;">DEALINGS IN THE SOFTWARE.<br>
<br>
</span>
</body>
</html>
using System.Collections;
using System.IO;
namespace Org.BouncyCastle.Asn1
{
public abstract class Asn1Generator
{
private Stream _out;
protected Asn1Generator(
Stream outStream)
{
_out = outStream;
}
protected Stream Out
{
get { return _out; }
}
public abstract void AddObject(Asn1Encodable obj);
public abstract Stream GetRawOutputStream();
public abstract void Close();
}
}
using System.IO;
namespace Org.BouncyCastle.Asn1
{
public interface Asn1OctetStringParser
: IAsn1Convertible
{
Stream GetOctetStream();
}
}
namespace Org.BouncyCastle.Asn1
{
public interface Asn1SequenceParser
: IAsn1Convertible
{
IAsn1Convertible ReadObject();
}
}
namespace Org.BouncyCastle.Asn1
{
public interface Asn1SetParser
: IAsn1Convertible
{
IAsn1Convertible ReadObject();
}
}
using System;
using System.IO;
namespace Org.BouncyCastle.Asn1
{
public class Asn1StreamParser
{
private readonly Stream _in;
private readonly int _limit;
private readonly byte[][] tmpBuffers;
public Asn1StreamParser(
Stream inStream)
: this(inStream, Asn1InputStream.FindLimit(inStream))
{
}
public Asn1StreamParser(
Stream inStream,
int limit)
{
if (!inStream.CanRead)
throw new ArgumentException("Expected stream to be readable", "inStream");
this._in = inStream;
this._limit = limit;
this.tmpBuffers = new byte[16][];
}
public Asn1StreamParser(
byte[] encoding)
: this(new MemoryStream(encoding, false), encoding.Length)
{
}
internal IAsn1Convertible ReadIndef(int tagValue)
{
// Note: INDEF => CONSTRUCTED
// TODO There are other tags that may be constructed (e.g. BIT_STRING)
switch (tagValue)
{
case Asn1Tags.External:
return new DerExternalParser(this);
case Asn1Tags.OctetString:
return new BerOctetStringParser(this);
case Asn1Tags.Sequence:
return new BerSequenceParser(this);
case Asn1Tags.Set:
return new BerSetParser(this);
default:
throw new Asn1Exception("unknown BER object encountered: 0x" + tagValue.ToString("X"));
}
}
internal IAsn1Convertible ReadImplicit(bool constructed, int tag)
{
if (_in is IndefiniteLengthInputStream)
{
if (!constructed)
throw new IOException("indefinite length primitive encoding encountered");
return ReadIndef(tag);
}
if (constructed)
{
switch (tag)
{
case Asn1Tags.Set:
return new DerSetParser(this);
case Asn1Tags.Sequence:
return new DerSequenceParser(this);
case Asn1Tags.OctetString:
return new BerOctetStringParser(this);
}
}
else
{
switch (tag)
{
case Asn1Tags.Set:
throw new Asn1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)");
case Asn1Tags.Sequence:
throw new Asn1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)");
case Asn1Tags.OctetString:
return new DerOctetStringParser((DefiniteLengthInputStream)_in);
}
}
throw new Asn1Exception("implicit tagging not implemented");
}
internal Asn1Object ReadTaggedObject(bool constructed, int tag)
{
if (!constructed)
{
// Note: !CONSTRUCTED => IMPLICIT
DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in;
return new DerTaggedObject(false, tag, new DerOctetString(defIn.ToArray()));
}
Asn1EncodableVector v = ReadVector();
if (_in is IndefiniteLengthInputStream)
{
return v.Count == 1
? new BerTaggedObject(true, tag, v[0])
: new BerTaggedObject(false, tag, BerSequence.FromVector(v));
}
return v.Count == 1
? new DerTaggedObject(true, tag, v[0])
: new DerTaggedObject(false, tag, DerSequence.FromVector(v));
}
public virtual IAsn1Convertible ReadObject()
{
int tag = _in.ReadByte();
if (tag == -1)
return null;
// turn of looking for "00" while we resolve the tag
Set00Check(false);
//
// calculate tag number
//
int tagNo = Asn1InputStream.ReadTagNumber(_in, tag);
bool isConstructed = (tag & Asn1Tags.Constructed) != 0;
//
// calculate length
//
int length = Asn1InputStream.ReadLength(_in, _limit);
if (length < 0) // indefinite length method
{
if (!isConstructed)
throw new IOException("indefinite length primitive encoding encountered");
IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit);
Asn1StreamParser sp = new Asn1StreamParser(indIn, _limit);
if ((tag & Asn1Tags.Application) != 0)
{
return new BerApplicationSpecificParser(tagNo, sp);
}
if ((tag & Asn1Tags.Tagged) != 0)
{
return new BerTaggedObjectParser(true, tagNo, sp);
}
return sp.ReadIndef(tagNo);
}
else
{
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length);
if ((tag & Asn1Tags.Application) != 0)
{
return new DerApplicationSpecific(isConstructed, tagNo, defIn.ToArray());
}
if ((tag & Asn1Tags.Tagged) != 0)
{
return new BerTaggedObjectParser(isConstructed, tagNo, new Asn1StreamParser(defIn));
}
if (isConstructed)
{
// TODO There are other tags that may be constructed (e.g. BitString)
switch (tagNo)
{
case Asn1Tags.OctetString:
//
// yes, people actually do this...
//
return new BerOctetStringParser(new Asn1StreamParser(defIn));
case Asn1Tags.Sequence:
return new DerSequenceParser(new Asn1StreamParser(defIn));
case Asn1Tags.Set:
return new DerSetParser(new Asn1StreamParser(defIn));
case Asn1Tags.External:
return new DerExternalParser(new Asn1StreamParser(defIn));
default:
throw new IOException("unknown tag " + tagNo + " encountered");
}
}
// Some primitive encodings can be handled by parsers too...
switch (tagNo)
{
case Asn1Tags.OctetString:
return new DerOctetStringParser(defIn);
}
try
{
return Asn1InputStream.CreatePrimitiveDerObject(tagNo, defIn, tmpBuffers);
}
catch (ArgumentException e)
{
throw new Asn1Exception("corrupted stream detected", e);
}
}
}
private void Set00Check(
bool enabled)
{
if (_in is IndefiniteLengthInputStream)
{
((IndefiniteLengthInputStream) _in).SetEofOn00(enabled);
}
}
internal Asn1EncodableVector ReadVector()
{
Asn1EncodableVector v = new Asn1EncodableVector();
IAsn1Convertible obj;
while ((obj = ReadObject()) != null)
{
v.Add(obj.ToAsn1Object());
}
return v;
}
}
}
namespace Org.BouncyCastle.Asn1
{
public interface Asn1TaggedObjectParser
: IAsn1Convertible
{
int TagNo { get; }
IAsn1Convertible GetObjectParser(int tag, bool isExplicit);
}
}
using System.IO;
namespace Org.BouncyCastle.Asn1
{
public abstract class Asn1Encodable
: IAsn1Convertible
{
public const string Der = "DER";
public const string Ber = "BER";
public byte[] GetEncoded()
{
MemoryStream bOut = new MemoryStream();
Asn1OutputStream aOut = new Asn1OutputStream(bOut);
aOut.WriteObject(this);
return bOut.ToArray();
}
public byte[] GetEncoded(
string encoding)
{
if (encoding.Equals(Der))
{
MemoryStream bOut = new MemoryStream();
DerOutputStream dOut = new DerOutputStream(bOut);
dOut.WriteObject(this);
return bOut.ToArray();
}
return GetEncoded();
}
/**
* Return the DER encoding of the object, null if the DER encoding can not be made.
*
* @return a DER byte array, null otherwise.
*/
public byte[] GetDerEncoded()
{
try
{
return GetEncoded(Der);
}
catch (IOException)
{
return null;
}
}
public sealed override int GetHashCode()
{
return ToAsn1Object().CallAsn1GetHashCode();
}
public sealed override bool Equals(
object obj)
{
if (obj == this)
return true;
IAsn1Convertible other = obj as IAsn1Convertible;
if (other == null)
return false;
Asn1Object o1 = ToAsn1Object();
Asn1Object o2 = other.ToAsn1Object();
return o1 == o2 || o1.CallAsn1Equals(o2);
}
public abstract Asn1Object ToAsn1Object();
}
}
using System;
using System.Collections;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
public class Asn1EncodableVector
: IEnumerable
{
private IList v = Platform.CreateArrayList();
public static Asn1EncodableVector FromEnumerable(
IEnumerable e)
{
Asn1EncodableVector v = new Asn1EncodableVector();
foreach (Asn1Encodable obj in e)
{
v.Add(obj);
}
return v;
}
// public Asn1EncodableVector()
// {
// }
public Asn1EncodableVector(
params Asn1Encodable[] v)
{
Add(v);
}
// public void Add(
// Asn1Encodable obj)
// {
// v.Add(obj);
// }
public void Add(
params Asn1Encodable[] objs)
{
foreach (Asn1Encodable obj in objs)
{
v.Add(obj);
}
}
public void AddOptional(
params Asn1Encodable[] objs)
{
if (objs != null)
{
foreach (Asn1Encodable obj in objs)
{
if (obj != null)
{
v.Add(obj);
}
}
}
}
public Asn1Encodable this[
int index]
{
get { return (Asn1Encodable) v[index]; }
}
[Obsolete("Use 'object[index]' syntax instead")]
public Asn1Encodable Get(
int index)
{
return this[index];
}
[Obsolete("Use 'Count' property instead")]
public int Size
{
get { return v.Count; }
}
public int Count
{
get { return v.Count; }
}
public IEnumerator GetEnumerator()
{
return v.GetEnumerator();
}
}
}
using System;
using System.IO;
namespace Org.BouncyCastle.Asn1
{
#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
[Serializable]
#endif
public class Asn1Exception
: IOException
{
public Asn1Exception()
: base()
{
}
public Asn1Exception(
string message)
: base(message)
{
}
public Asn1Exception(
string message,
Exception exception)
: base(message, exception)
{
}
}
}
namespace Org.BouncyCastle.Asn1
{
/**
* A Null object.
*/
public abstract class Asn1Null
: Asn1Object
{
internal Asn1Null()
{
}
public override string ToString()
{
return "NULL";
}
}
}
using System;
using System.IO;
namespace Org.BouncyCastle.Asn1
{
public abstract class Asn1Object
: Asn1Encodable
{
/// <summary>Create a base ASN.1 object from a byte array.</summary>
/// <param name="data">The byte array to parse.</param>
/// <returns>The base ASN.1 object represented by the byte array.</returns>
/// <exception cref="IOException">If there is a problem parsing the data.</exception>
public static Asn1Object FromByteArray(
byte[] data)
{
try
{
MemoryStream input = new MemoryStream(data, false);
Asn1InputStream asn1 = new Asn1InputStream(input, data.Length);
Asn1Object result = asn1.ReadObject();
if (input.Position != input.Length)
throw new IOException("extra data found after object");
return result;
}
catch (InvalidCastException)
{
throw new IOException("cannot recognise object in byte array");
}
}
/// <summary>Read a base ASN.1 object from a stream.</summary>
/// <param name="inStr">The stream to parse.</param>
/// <returns>The base ASN.1 object represented by the byte array.</returns>
/// <exception cref="IOException">If there is a problem parsing the data.</exception>
public static Asn1Object FromStream(
Stream inStr)
{
try
{
return new Asn1InputStream(inStr).ReadObject();
}
catch (InvalidCastException)
{
throw new IOException("cannot recognise object in stream");
}
}
public sealed override Asn1Object ToAsn1Object()
{
return this;
}
internal abstract void Encode(DerOutputStream derOut);
protected abstract bool Asn1Equals(Asn1Object asn1Object);
protected abstract int Asn1GetHashCode();
internal bool CallAsn1Equals(Asn1Object obj)
{
return Asn1Equals(obj);
}
internal int CallAsn1GetHashCode()
{
return Asn1GetHashCode();
}
}
}
using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Asn1
{
public abstract class Asn1OctetString
: Asn1Object, Asn1OctetStringParser
{
internal byte[] str;
/**
* return an Octet string from a tagged object.
*
* @param obj the tagged object holding the object we want.
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static Asn1OctetString GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is Asn1OctetString)
{
return GetInstance(o);
}
return BerOctetString.FromSequence(Asn1Sequence.GetInstance(o));
}
/**
* return an Octet string from the given object.
*
* @param obj the object we want converted.
* @exception ArgumentException if the object cannot be converted.
*/
public static Asn1OctetString GetInstance(object obj)
{
if (obj == null || obj is Asn1OctetString)
{
return (Asn1OctetString)obj;
}
// TODO: this needs to be deleted in V2
if (obj is Asn1TaggedObject)
return GetInstance(((Asn1TaggedObject)obj).GetObject());
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* @param string the octets making up the octet string.
*/
internal Asn1OctetString(
byte[] str)
{
if (str == null)
throw new ArgumentNullException("str");
this.str = str;
}
internal Asn1OctetString(
Asn1Encodable obj)
{
try
{
this.str = obj.GetEncoded(Asn1Encodable.Der);
}
catch (IOException e)
{
throw new ArgumentException("Error processing object : " + e.ToString());
}
}
public Stream GetOctetStream()
{
return new MemoryStream(str, false);
}
public Asn1OctetStringParser Parser
{
get { return this; }
}
public virtual byte[] GetOctets()
{
return str;
}
protected override int Asn1GetHashCode()
{
return Arrays.GetHashCode(GetOctets());
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerOctetString other = asn1Object as DerOctetString;
if (other == null)
return false;
return Arrays.AreEqual(GetOctets(), other.GetOctets());
}
public override string ToString()
{
return "#" + Hex.ToHexString(str);
}
}
}
using System;
using System.IO;
namespace Org.BouncyCastle.Asn1
{
public class Asn1OutputStream
: DerOutputStream
{
public Asn1OutputStream(Stream os) : base(os)
{
}
[Obsolete("Use version taking an Asn1Encodable arg instead")]
public override void WriteObject(
object obj)
{
if (obj == null)
{
WriteNull();
}
else if (obj is Asn1Object)
{
((Asn1Object)obj).Encode(this);
}
else if (obj is Asn1Encodable)
{
((Asn1Encodable)obj).ToAsn1Object().Encode(this);
}
else
{
throw new IOException("object not Asn1Encodable");
}
}
}
}
using System;
namespace Org.BouncyCastle.Asn1
{
#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE)
[Serializable]
#endif
public class Asn1ParsingException
: InvalidOperationException
{
public Asn1ParsingException()
: base()
{
}
public Asn1ParsingException(
string message)
: base(message)
{
}
public Asn1ParsingException(
string message,
Exception exception)
: base(message, exception)
{
}
}
}
using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
namespace Org.BouncyCastle.Asn1
{
public abstract class Asn1Sequence
: Asn1Object, IEnumerable
{
private readonly IList seq;
/**
* return an Asn1Sequence from the given object.
*
* @param obj the object we want converted.
* @exception ArgumentException if the object cannot be converted.
*/
public static Asn1Sequence GetInstance(
object obj)
{
if (obj == null || obj is Asn1Sequence)
{
return (Asn1Sequence)obj;
}
else if (obj is Asn1SequenceParser)
{
return Asn1Sequence.GetInstance(((Asn1SequenceParser)obj).ToAsn1Object());
}
else if (obj is byte[])
{
try
{
return Asn1Sequence.GetInstance(FromByteArray((byte[])obj));
}
catch (IOException e)
{
throw new ArgumentException("failed to construct sequence from byte[]: " + e.Message);
}
}
else if (obj is Asn1Encodable)
{
Asn1Object primitive = ((Asn1Encodable)obj).ToAsn1Object();
if (primitive is Asn1Sequence)
{
return (Asn1Sequence)primitive;
}
}
throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
/**
* Return an ASN1 sequence from a tagged object. There is a special
* case here, if an object appears to have been explicitly tagged on
* reading but we were expecting it to be implicitly tagged in the
* normal course of events it indicates that we lost the surrounding
* sequence - so we need to add it back (this will happen if the tagged
* object is a sequence that contains other sequences). If you are
* dealing with implicitly tagged sequences you really <b>should</b>
* be using this method.
*
* @param obj the tagged object.
* @param explicitly true if the object is meant to be explicitly tagged,
* false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static Asn1Sequence GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
Asn1Object inner = obj.GetObject();
if (explicitly)
{
if (!obj.IsExplicit())
throw new ArgumentException("object implicit - explicit expected.");
return (Asn1Sequence) inner;
}
//
// constructed object which appears to be explicitly tagged
// when it should be implicit means we have to add the
// surrounding sequence.
//
if (obj.IsExplicit())
{
if (obj is BerTaggedObject)
{
return new BerSequence(inner);
}
return new DerSequence(inner);
}
if (inner is Asn1Sequence)
{
return (Asn1Sequence) inner;
}
throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
protected internal Asn1Sequence(
int capacity)
{
seq = Platform.CreateArrayList(capacity);
}
public virtual IEnumerator GetEnumerator()
{
return seq.GetEnumerator();
}
[Obsolete("Use GetEnumerator() instead")]
public IEnumerator GetObjects()
{
return GetEnumerator();
}
private class Asn1SequenceParserImpl
: Asn1SequenceParser
{
private readonly Asn1Sequence outer;
private readonly int max;
private int index;
public Asn1SequenceParserImpl(
Asn1Sequence outer)
{
this.outer = outer;
this.max = outer.Count;
}
public IAsn1Convertible ReadObject()
{
if (index == max)
return null;
Asn1Encodable obj = outer[index++];
if (obj is Asn1Sequence)
return ((Asn1Sequence)obj).Parser;
if (obj is Asn1Set)
return ((Asn1Set)obj).Parser;
// NB: Asn1OctetString implements Asn1OctetStringParser directly
// if (obj is Asn1OctetString)
// return ((Asn1OctetString)obj).Parser;
return obj;
}
public Asn1Object ToAsn1Object()
{
return outer;
}
}
public virtual Asn1SequenceParser Parser
{
get { return new Asn1SequenceParserImpl(this); }
}
/**
* return the object at the sequence position indicated by index.
*
* @param index the sequence number (starting at zero) of the object
* @return the object at the sequence position indicated by index.
*/
public virtual Asn1Encodable this[int index]
{
get { return (Asn1Encodable) seq[index]; }
}
[Obsolete("Use 'object[index]' syntax instead")]
public Asn1Encodable GetObjectAt(
int index)
{
return this[index];
}
[Obsolete("Use 'Count' property instead")]
public int Size
{
get { return Count; }
}
public virtual int Count
{
get { return seq.Count; }
}
protected override int Asn1GetHashCode()
{
int hc = Count;
foreach (object o in this)
{
hc *= 17;
if (o == null)
{
hc ^= DerNull.Instance.GetHashCode();
}
else
{
hc ^= o.GetHashCode();
}
}
return hc;
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
Asn1Sequence other = asn1Object as Asn1Sequence;
if (other == null)
return false;
if (Count != other.Count)
return false;
IEnumerator s1 = GetEnumerator();
IEnumerator s2 = other.GetEnumerator();
while (s1.MoveNext() && s2.MoveNext())
{
Asn1Object o1 = GetCurrent(s1).ToAsn1Object();
Asn1Object o2 = GetCurrent(s2).ToAsn1Object();
if (!o1.Equals(o2))
return false;
}
return true;
}
private Asn1Encodable GetCurrent(IEnumerator e)
{
Asn1Encodable encObj = (Asn1Encodable)e.Current;
// unfortunately null was allowed as a substitute for DER null
if (encObj == null)
return DerNull.Instance;
return encObj;
}
protected internal void AddObject(
Asn1Encodable obj)
{
seq.Add(obj);
}
public override string ToString()
{
return CollectionUtilities.ToString(seq);
}
}
}
using System;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
/**
* ASN.1 TaggedObject - in ASN.1 notation this is any object preceded by
* a [n] where n is some number - these are assumed to follow the construction
* rules (as with sequences).
*/
public abstract class Asn1TaggedObject
: Asn1Object, Asn1TaggedObjectParser
{
internal static bool IsConstructed(bool isExplicit, Asn1Object obj)
{
if (isExplicit || obj is Asn1Sequence || obj is Asn1Set)
return true;
Asn1TaggedObject tagged = obj as Asn1TaggedObject;
if (tagged == null)
return false;
return IsConstructed(tagged.IsExplicit(), tagged.GetObject());
}
internal int tagNo;
// internal bool empty;
internal bool explicitly = true;
internal Asn1Encodable obj;
static public Asn1TaggedObject GetInstance(
Asn1TaggedObject obj,
bool explicitly)
{
if (explicitly)
{
return (Asn1TaggedObject) obj.GetObject();
}
throw new ArgumentException("implicitly tagged tagged object");
}
static public Asn1TaggedObject GetInstance(
object obj)
{
if (obj == null || obj is Asn1TaggedObject)
{
return (Asn1TaggedObject) obj;
}
throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
/**
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
protected Asn1TaggedObject(
int tagNo,
Asn1Encodable obj)
{
this.explicitly = true;
this.tagNo = tagNo;
this.obj = obj;
}
/**
* @param explicitly true if the object is explicitly tagged.
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
protected Asn1TaggedObject(
bool explicitly,
int tagNo,
Asn1Encodable obj)
{
// IAsn1Choice marker interface 'insists' on explicit tagging
this.explicitly = explicitly || (obj is IAsn1Choice);
this.tagNo = tagNo;
this.obj = obj;
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
Asn1TaggedObject other = asn1Object as Asn1TaggedObject;
if (other == null)
return false;
return this.tagNo == other.tagNo
// && this.empty == other.empty
&& this.explicitly == other.explicitly // TODO Should this be part of equality?
&& Platform.Equals(GetObject(), other.GetObject());
}
protected override int Asn1GetHashCode()
{
int code = tagNo.GetHashCode();
// TODO: actually this is wrong - the problem is that a re-encoded
// object may end up with a different hashCode due to implicit
// tagging. As implicit tagging is ambiguous if a sequence is involved
// it seems the only correct method for both equals and hashCode is to
// compare the encodings...
// code ^= explicitly.GetHashCode();
if (obj != null)
{
code ^= obj.GetHashCode();
}
return code;
}
public int TagNo
{
get { return tagNo; }
}
/**
* return whether or not the object may be explicitly tagged.
* <p>
* Note: if the object has been read from an input stream, the only
* time you can be sure if isExplicit is returning the true state of
* affairs is if it returns false. An implicitly tagged object may appear
* to be explicitly tagged, so you need to understand the context under
* which the reading was done as well, see GetObject below.</p>
*/
public bool IsExplicit()
{
return explicitly;
}
public bool IsEmpty()
{
return false; //empty;
}
/**
* return whatever was following the tag.
* <p>
* Note: tagged objects are generally context dependent if you're
* trying to extract a tagged object you should be going via the
* appropriate GetInstance method.</p>
*/
public Asn1Object GetObject()
{
if (obj != null)
{
return obj.ToAsn1Object();
}
return null;
}
/**
* Return the object held in this tagged object as a parser assuming it has
* the type of the passed in tag. If the object doesn't have a parser
* associated with it, the base object is returned.
*/
public IAsn1Convertible GetObjectParser(
int tag,
bool isExplicit)
{
switch (tag)
{
case Asn1Tags.Set:
return Asn1Set.GetInstance(this, isExplicit).Parser;
case Asn1Tags.Sequence:
return Asn1Sequence.GetInstance(this, isExplicit).Parser;
case Asn1Tags.OctetString:
return Asn1OctetString.GetInstance(this, isExplicit).Parser;
}
if (isExplicit)
{
return GetObject();
}
throw Platform.CreateNotImplementedException("implicit tagging for tag: " + tag);
}
public override string ToString()
{
return "[" + tagNo + "]" + obj;
}
}
}
namespace Org.BouncyCastle.Asn1
{
public class Asn1Tags
{
public const int Boolean = 0x01;
public const int Integer = 0x02;
public const int BitString = 0x03;
public const int OctetString = 0x04;
public const int Null = 0x05;
public const int ObjectIdentifier = 0x06;
public const int External = 0x08;
public const int Enumerated = 0x0a;
public const int Sequence = 0x10;
public const int SequenceOf = 0x10; // for completeness
public const int Set = 0x11;
public const int SetOf = 0x11; // for completeness
public const int NumericString = 0x12;
public const int PrintableString = 0x13;
public const int T61String = 0x14;
public const int VideotexString = 0x15;
public const int IA5String = 0x16;
public const int UtcTime = 0x17;
public const int GeneralizedTime = 0x18;
public const int GraphicString = 0x19;
public const int VisibleString = 0x1a;
public const int GeneralString = 0x1b;
public const int UniversalString = 0x1c;
public const int BmpString = 0x1e;
public const int Utf8String = 0x0c;
public const int Constructed = 0x20;
public const int Application = 0x40;
public const int Tagged = 0x80;
}
}
using System;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
public class BerBitString
: DerBitString
{
public BerBitString(byte[] data, int padBits)
: base(data, padBits)
{
}
public BerBitString(byte[] data)
: base(data)
{
}
public BerBitString(int namedBits)
: base(namedBits)
{
}
public BerBitString(Asn1Encodable obj)
: base(obj)
{
}
internal override void Encode(
DerOutputStream derOut)
{
if (derOut is Asn1OutputStream || derOut is BerOutputStream)
{
derOut.WriteEncoded(Asn1Tags.BitString, (byte)mPadBits, mData);
}
else
{
base.Encode(derOut);
}
}
}
}
using System.IO;
using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Asn1
{
public class BerGenerator
: Asn1Generator
{
private bool _tagged = false;
private bool _isExplicit;
private int _tagNo;
protected BerGenerator(
Stream outStream)
: base(outStream)
{
}
public BerGenerator(
Stream outStream,
int tagNo,
bool isExplicit)
: base(outStream)
{
_tagged = true;
_isExplicit = isExplicit;
_tagNo = tagNo;
}
public override void AddObject(
Asn1Encodable obj)
{
new BerOutputStream(Out).WriteObject(obj);
}
public override Stream GetRawOutputStream()
{
return Out;
}
public override void Close()
{
WriteBerEnd();
}
private void WriteHdr(
int tag)
{
Out.WriteByte((byte) tag);
Out.WriteByte(0x80);
}
protected void WriteBerHeader(
int tag)
{
if (_tagged)
{
int tagNum = _tagNo | Asn1Tags.Tagged;
if (_isExplicit)
{
WriteHdr(tagNum | Asn1Tags.Constructed);
WriteHdr(tag);
}
else
{
if ((tag & Asn1Tags.Constructed) != 0)
{
WriteHdr(tagNum | Asn1Tags.Constructed);
}
else
{
WriteHdr(tagNum);
}
}
}
else
{
WriteHdr(tag);
}
}
protected void WriteBerBody(
Stream contentStream)
{
Streams.PipeAll(contentStream, Out);
}
protected void WriteBerEnd()
{
Out.WriteByte(0x00);
Out.WriteByte(0x00);
if (_tagged && _isExplicit) // write extra end for tag header
{
Out.WriteByte(0x00);
Out.WriteByte(0x00);
}
}
}
}
using System;
using System.IO;
using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Asn1
{
public class BerOctetStringGenerator
: BerGenerator
{
public BerOctetStringGenerator(Stream outStream)
: base(outStream)
{
WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.OctetString);
}
public BerOctetStringGenerator(
Stream outStream,
int tagNo,
bool isExplicit)
: base(outStream, tagNo, isExplicit)
{
WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.OctetString);
}
public Stream GetOctetOutputStream()
{
return GetOctetOutputStream(new byte[1000]); // limit for CER encoding.
}
public Stream GetOctetOutputStream(
int bufSize)
{
return bufSize < 1
? GetOctetOutputStream()
: GetOctetOutputStream(new byte[bufSize]);
}
public Stream GetOctetOutputStream(
byte[] buf)
{
return new BufferedBerOctetStream(this, buf);
}
private class BufferedBerOctetStream
: BaseOutputStream
{
private byte[] _buf;
private int _off;
private readonly BerOctetStringGenerator _gen;
private readonly DerOutputStream _derOut;
internal BufferedBerOctetStream(
BerOctetStringGenerator gen,
byte[] buf)
{
_gen = gen;
_buf = buf;
_off = 0;
_derOut = new DerOutputStream(_gen.Out);
}
public override void WriteByte(
byte b)
{
_buf[_off++] = b;
if (_off == _buf.Length)
{
DerOctetString.Encode(_derOut, _buf, 0, _off);
_off = 0;
}
}
public override void Write(
byte[] buf,
int offset,
int len)
{
while (len > 0)
{
int numToCopy = System.Math.Min(len, _buf.Length - _off);
if (numToCopy == _buf.Length)
{
DerOctetString.Encode(_derOut, buf, offset, numToCopy);
}
else
{
Array.Copy(buf, offset, _buf, _off, numToCopy);
_off += numToCopy;
if (_off < _buf.Length)
break;
DerOctetString.Encode(_derOut, _buf, 0, _off);
_off = 0;
}
offset += numToCopy;
len -= numToCopy;
}
}
#if PORTABLE
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (_off != 0)
{
DerOctetString.Encode(_derOut, _buf, 0, _off);
}
_gen.WriteBerEnd();
}
base.Dispose(disposing);
}
#else
public override void Close()
{
if (_off != 0)
{
DerOctetString.Encode(_derOut, _buf, 0, _off);
}
_gen.WriteBerEnd();
base.Close();
}
#endif
}
}
}
using System;
using System.IO;
using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Asn1
{
public class BerOctetStringParser
: Asn1OctetStringParser
{
private readonly Asn1StreamParser _parser;
internal BerOctetStringParser(
Asn1StreamParser parser)
{
_parser = parser;
}
public Stream GetOctetStream()
{
return new ConstructedOctetStream(_parser);
}
public Asn1Object ToAsn1Object()
{
try
{
return new BerOctetString(Streams.ReadAll(GetOctetStream()));
}
catch (IOException e)
{
throw new Asn1ParsingException("IOException converting stream to byte array: " + e.Message, e);
}
}
}
}
using System.IO;
namespace Org.BouncyCastle.Asn1
{
public class BerSequenceGenerator
: BerGenerator
{
public BerSequenceGenerator(
Stream outStream)
: base(outStream)
{
WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Sequence);
}
public BerSequenceGenerator(
Stream outStream,
int tagNo,
bool isExplicit)
: base(outStream, tagNo, isExplicit)
{
WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Sequence);
}
}
}
namespace Org.BouncyCastle.Asn1
{
public class BerSequenceParser
: Asn1SequenceParser
{
private readonly Asn1StreamParser _parser;
internal BerSequenceParser(
Asn1StreamParser parser)
{
this._parser = parser;
}
public IAsn1Convertible ReadObject()
{
return _parser.ReadObject();
}
public Asn1Object ToAsn1Object()
{
return new BerSequence(_parser.ReadVector());
}
}
}
using System.IO;
namespace Org.BouncyCastle.Asn1
{
public class BerSetGenerator
: BerGenerator
{
public BerSetGenerator(
Stream outStream)
: base(outStream)
{
WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Set);
}
public BerSetGenerator(
Stream outStream,
int tagNo,
bool isExplicit)
: base(outStream, tagNo, isExplicit)
{
WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Set);
}
}
}
namespace Org.BouncyCastle.Asn1
{
public class BerSetParser
: Asn1SetParser
{
private readonly Asn1StreamParser _parser;
internal BerSetParser(
Asn1StreamParser parser)
{
this._parser = parser;
}
public IAsn1Convertible ReadObject()
{
return _parser.ReadObject();
}
public Asn1Object ToAsn1Object()
{
return new BerSet(_parser.ReadVector(), false);
}
}
}
using System;
using System.IO;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
public class BerTaggedObjectParser
: Asn1TaggedObjectParser
{
private bool _constructed;
private int _tagNumber;
private Asn1StreamParser _parser;
[Obsolete]
internal BerTaggedObjectParser(
int baseTag,
int tagNumber,
Stream contentStream)
: this((baseTag & Asn1Tags.Constructed) != 0, tagNumber, new Asn1StreamParser(contentStream))
{
}
internal BerTaggedObjectParser(
bool constructed,
int tagNumber,
Asn1StreamParser parser)
{
_constructed = constructed;
_tagNumber = tagNumber;
_parser = parser;
}
public bool IsConstructed
{
get { return _constructed; }
}
public int TagNo
{
get { return _tagNumber; }
}
public IAsn1Convertible GetObjectParser(
int tag,
bool isExplicit)
{
if (isExplicit)
{
if (!_constructed)
throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
return _parser.ReadObject();
}
return _parser.ReadImplicit(_constructed, tag);
}
public Asn1Object ToAsn1Object()
{
try
{
return _parser.ReadTaggedObject(_constructed, _tagNumber);
}
catch (IOException e)
{
throw new Asn1ParsingException(e.Message);
}
}
}
}
using System;
namespace Org.BouncyCastle.Asn1
{
public class BerApplicationSpecific
: DerApplicationSpecific
{
public BerApplicationSpecific(
int tagNo,
Asn1EncodableVector vec)
: base(tagNo, vec)
{
}
}
}
using System;
namespace Org.BouncyCastle.Asn1
{
public class BerApplicationSpecificParser
: IAsn1ApplicationSpecificParser
{
private readonly int tag;
private readonly Asn1StreamParser parser;
internal BerApplicationSpecificParser(
int tag,
Asn1StreamParser parser)
{
this.tag = tag;
this.parser = parser;
}
public IAsn1Convertible ReadObject()
{
return parser.ReadObject();
}
public Asn1Object ToAsn1Object()
{
return new BerApplicationSpecific(tag, parser.ReadVector());
}
}
}
using System;
namespace Org.BouncyCastle.Asn1
{
/**
* A BER Null object.
*/
public class BerNull
: DerNull
{
public static new readonly BerNull Instance = new BerNull(0);
[Obsolete("Use static Instance object")]
public BerNull()
{
}
private BerNull(int dummy) : base(dummy)
{
}
internal override void Encode(
DerOutputStream derOut)
{
if (derOut is Asn1OutputStream || derOut is BerOutputStream)
{
derOut.WriteByte(Asn1Tags.Null);
}
else
{
base.Encode(derOut);
}
}
}
}
using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
public class BerOctetString
: DerOctetString, IEnumerable
{
public static BerOctetString FromSequence(Asn1Sequence seq)
{
IList v = Platform.CreateArrayList();
foreach (Asn1Encodable obj in seq)
{
v.Add(obj);
}
return new BerOctetString(v);
}
private const int MaxLength = 1000;
/**
* convert a vector of octet strings into a single byte string
*/
private static byte[] ToBytes(
IEnumerable octs)
{
MemoryStream bOut = new MemoryStream();
foreach (DerOctetString o in octs)
{
byte[] octets = o.GetOctets();
bOut.Write(octets, 0, octets.Length);
}
return bOut.ToArray();
}
private readonly IEnumerable octs;
/// <param name="str">The octets making up the octet string.</param>
public BerOctetString(
byte[] str)
: base(str)
{
}
public BerOctetString(
IEnumerable octets)
: base(ToBytes(octets))
{
this.octs = octets;
}
public BerOctetString(
Asn1Object obj)
: base(obj)
{
}
public BerOctetString(
Asn1Encodable obj)
: base(obj.ToAsn1Object())
{
}
public override byte[] GetOctets()
{
return str;
}
/**
* return the DER octets that make up this string.
*/
public IEnumerator GetEnumerator()
{
if (octs == null)
{
return GenerateOcts().GetEnumerator();
}
return octs.GetEnumerator();
}
[Obsolete("Use GetEnumerator() instead")]
public IEnumerator GetObjects()
{
return GetEnumerator();
}
private IList GenerateOcts()
{
IList vec = Platform.CreateArrayList();
for (int i = 0; i < str.Length; i += MaxLength)
{
int end = System.Math.Min(str.Length, i + MaxLength);
byte[] nStr = new byte[end - i];
Array.Copy(str, i, nStr, 0, nStr.Length);
vec.Add(new DerOctetString(nStr));
}
return vec;
}
internal override void Encode(
DerOutputStream derOut)
{
if (derOut is Asn1OutputStream || derOut is BerOutputStream)
{
derOut.WriteByte(Asn1Tags.Constructed | Asn1Tags.OctetString);
derOut.WriteByte(0x80);
//
// write out the octet array
//
foreach (DerOctetString oct in this)
{
derOut.WriteObject(oct);
}
derOut.WriteByte(0x00);
derOut.WriteByte(0x00);
}
else
{
base.Encode(derOut);
}
}
}
}
using System;
using System.IO;
namespace Org.BouncyCastle.Asn1
{
// TODO Make Obsolete in favour of Asn1OutputStream?
public class BerOutputStream
: DerOutputStream
{
public BerOutputStream(Stream os) : base(os)
{
}
[Obsolete("Use version taking an Asn1Encodable arg instead")]
public override void WriteObject(
object obj)
{
if (obj == null)
{
WriteNull();
}
else if (obj is Asn1Object)
{
((Asn1Object)obj).Encode(this);
}
else if (obj is Asn1Encodable)
{
((Asn1Encodable)obj).ToAsn1Object().Encode(this);
}
else
{
throw new IOException("object not BerEncodable");
}
}
}
}
namespace Org.BouncyCastle.Asn1
{
public class BerSequence
: DerSequence
{
public static new readonly BerSequence Empty = new BerSequence();
public static new BerSequence FromVector(
Asn1EncodableVector v)
{
return v.Count < 1 ? Empty : new BerSequence(v);
}
/**
* create an empty sequence
*/
public BerSequence()
{
}
/**
* create a sequence containing one object
*/
public BerSequence(
Asn1Encodable obj)
: base(obj)
{
}
public BerSequence(
params Asn1Encodable[] v)
: base(v)
{
}
/**
* create a sequence containing a vector of objects.
*/
public BerSequence(
Asn1EncodableVector v)
: base(v)
{
}
/*
*/
internal override void Encode(
DerOutputStream derOut)
{
if (derOut is Asn1OutputStream || derOut is BerOutputStream)
{
derOut.WriteByte(Asn1Tags.Sequence | Asn1Tags.Constructed);
derOut.WriteByte(0x80);
foreach (Asn1Encodable o in this)
{
derOut.WriteObject(o);
}
derOut.WriteByte(0x00);
derOut.WriteByte(0x00);
}
else
{
base.Encode(derOut);
}
}
}
}
namespace Org.BouncyCastle.Asn1
{
public class BerSet
: DerSet
{
public static new readonly BerSet Empty = new BerSet();
public static new BerSet FromVector(
Asn1EncodableVector v)
{
return v.Count < 1 ? Empty : new BerSet(v);
}
internal static new BerSet FromVector(
Asn1EncodableVector v,
bool needsSorting)
{
return v.Count < 1 ? Empty : new BerSet(v, needsSorting);
}
/**
* create an empty sequence
*/
public BerSet()
{
}
/**
* create a set containing one object
*/
public BerSet(Asn1Encodable obj) : base(obj)
{
}
/**
* create a set containing a vector of objects.
*/
public BerSet(Asn1EncodableVector v) : base(v, false)
{
}
internal BerSet(Asn1EncodableVector v, bool needsSorting) : base(v, needsSorting)
{
}
/*
*/
internal override void Encode(
DerOutputStream derOut)
{
if (derOut is Asn1OutputStream || derOut is BerOutputStream)
{
derOut.WriteByte(Asn1Tags.Set | Asn1Tags.Constructed);
derOut.WriteByte(0x80);
foreach (Asn1Encodable o in this)
{
derOut.WriteObject(o);
}
derOut.WriteByte(0x00);
derOut.WriteByte(0x00);
}
else
{
base.Encode(derOut);
}
}
}
}
using System;
using System.Collections;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
/**
* BER TaggedObject - in ASN.1 notation this is any object preceded by
* a [n] where n is some number - these are assumed to follow the construction
* rules (as with sequences).
*/
public class BerTaggedObject
: DerTaggedObject
{
/**
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
public BerTaggedObject(
int tagNo,
Asn1Encodable obj)
: base(tagNo, obj)
{
}
/**
* @param explicitly true if an explicitly tagged object.
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
public BerTaggedObject(
bool explicitly,
int tagNo,
Asn1Encodable obj)
: base(explicitly, tagNo, obj)
{
}
/**
* create an implicitly tagged object that contains a zero
* length sequence.
*/
public BerTaggedObject(
int tagNo)
: base(false, tagNo, BerSequence.Empty)
{
}
internal override void Encode(
DerOutputStream derOut)
{
if (derOut is Asn1OutputStream || derOut is BerOutputStream)
{
derOut.WriteTag((byte)(Asn1Tags.Constructed | Asn1Tags.Tagged), tagNo);
derOut.WriteByte(0x80);
if (!IsEmpty())
{
if (!explicitly)
{
IEnumerable eObj;
if (obj is Asn1OctetString)
{
if (obj is BerOctetString)
{
eObj = (BerOctetString) obj;
}
else
{
Asn1OctetString octs = (Asn1OctetString)obj;
eObj = new BerOctetString(octs.GetOctets());
}
}
else if (obj is Asn1Sequence)
{
eObj = (Asn1Sequence) obj;
}
else if (obj is Asn1Set)
{
eObj = (Asn1Set) obj;
}
else
{
throw Platform.CreateNotImplementedException(Platform.GetTypeName(obj));
}
foreach (Asn1Encodable o in eObj)
{
derOut.WriteObject(o);
}
}
else
{
derOut.WriteObject(obj);
}
}
derOut.WriteByte(0x00);
derOut.WriteByte(0x00);
}
else
{
base.Encode(derOut);
}
}
}
}
using System.IO;
using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Asn1
{
internal class ConstructedOctetStream
: BaseInputStream
{
private readonly Asn1StreamParser _parser;
private bool _first = true;
private Stream _currentStream;
internal ConstructedOctetStream(
Asn1StreamParser parser)
{
_parser = parser;
}
public override int Read(byte[] buffer, int offset, int count)
{
if (_currentStream == null)
{
if (!_first)
return 0;
Asn1OctetStringParser s = (Asn1OctetStringParser)_parser.ReadObject();
if (s == null)
return 0;
_first = false;
_currentStream = s.GetOctetStream();
}
int totalRead = 0;
for (;;)
{
int numRead = _currentStream.Read(buffer, offset + totalRead, count - totalRead);
if (numRead > 0)
{
totalRead += numRead;
if (totalRead == count)
return totalRead;
}
else
{
Asn1OctetStringParser aos = (Asn1OctetStringParser)_parser.ReadObject();
if (aos == null)
{
_currentStream = null;
return totalRead;
}
_currentStream = aos.GetOctetStream();
}
}
}
public override int ReadByte()
{
if (_currentStream == null)
{
if (!_first)
return 0;
Asn1OctetStringParser s = (Asn1OctetStringParser)_parser.ReadObject();
if (s == null)
return 0;
_first = false;
_currentStream = s.GetOctetStream();
}
for (;;)
{
int b = _currentStream.ReadByte();
if (b >= 0)
{
return b;
}
Asn1OctetStringParser aos = (Asn1OctetStringParser)_parser.ReadObject();
if (aos == null)
{
_currentStream = null;
return -1;
}
_currentStream = aos.GetOctetStream();
}
}
}
}
using System;
using System.IO;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
/**
* Class representing the DER-type External
*/
public class DerExternal
: Asn1Object
{
private DerObjectIdentifier directReference;
private DerInteger indirectReference;
private Asn1Object dataValueDescriptor;
private int encoding;
private Asn1Object externalContent;
public DerExternal(
Asn1EncodableVector vector)
{
int offset = 0;
Asn1Object enc = GetObjFromVector(vector, offset);
if (enc is DerObjectIdentifier)
{
directReference = (DerObjectIdentifier)enc;
offset++;
enc = GetObjFromVector(vector, offset);
}
if (enc is DerInteger)
{
indirectReference = (DerInteger) enc;
offset++;
enc = GetObjFromVector(vector, offset);
}
if (!(enc is Asn1TaggedObject))
{
dataValueDescriptor = enc;
offset++;
enc = GetObjFromVector(vector, offset);
}
if (vector.Count != offset + 1)
throw new ArgumentException("input vector too large", "vector");
if (!(enc is Asn1TaggedObject))
throw new ArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External", "vector");
Asn1TaggedObject obj = (Asn1TaggedObject)enc;
// Use property accessor to include check on value
Encoding = obj.TagNo;
if (encoding < 0 || encoding > 2)
throw new InvalidOperationException("invalid encoding value");
externalContent = obj.GetObject();
}
/**
* Creates a new instance of DerExternal
* See X.690 for more informations about the meaning of these parameters
* @param directReference The direct reference or <code>null</code> if not set.
* @param indirectReference The indirect reference or <code>null</code> if not set.
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param externalData The external data in its encoded form.
*/
public DerExternal(DerObjectIdentifier directReference, DerInteger indirectReference, Asn1Object dataValueDescriptor, DerTaggedObject externalData)
: this(directReference, indirectReference, dataValueDescriptor, externalData.TagNo, externalData.ToAsn1Object())
{
}
/**
* Creates a new instance of DerExternal.
* See X.690 for more informations about the meaning of these parameters
* @param directReference The direct reference or <code>null</code> if not set.
* @param indirectReference The indirect reference or <code>null</code> if not set.
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param encoding The encoding to be used for the external data
* @param externalData The external data
*/
public DerExternal(DerObjectIdentifier directReference, DerInteger indirectReference, Asn1Object dataValueDescriptor, int encoding, Asn1Object externalData)
{
DirectReference = directReference;
IndirectReference = indirectReference;
DataValueDescriptor = dataValueDescriptor;
Encoding = encoding;
ExternalContent = externalData.ToAsn1Object();
}
internal override void Encode(DerOutputStream derOut)
{
MemoryStream ms = new MemoryStream();
WriteEncodable(ms, directReference);
WriteEncodable(ms, indirectReference);
WriteEncodable(ms, dataValueDescriptor);
WriteEncodable(ms, new DerTaggedObject(Asn1Tags.External, externalContent));
derOut.WriteEncoded(Asn1Tags.Constructed, Asn1Tags.External, ms.ToArray());
}
protected override int Asn1GetHashCode()
{
int ret = externalContent.GetHashCode();
if (directReference != null)
{
ret ^= directReference.GetHashCode();
}
if (indirectReference != null)
{
ret ^= indirectReference.GetHashCode();
}
if (dataValueDescriptor != null)
{
ret ^= dataValueDescriptor.GetHashCode();
}
return ret;
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
if (this == asn1Object)
return true;
DerExternal other = asn1Object as DerExternal;
if (other == null)
return false;
return Platform.Equals(directReference, other.directReference)
&& Platform.Equals(indirectReference, other.indirectReference)
&& Platform.Equals(dataValueDescriptor, other.dataValueDescriptor)
&& externalContent.Equals(other.externalContent);
}
public Asn1Object DataValueDescriptor
{
get { return dataValueDescriptor; }
set { this.dataValueDescriptor = value; }
}
public DerObjectIdentifier DirectReference
{
get { return directReference; }
set { this.directReference = value; }
}
/**
* The encoding of the content. Valid values are
* <ul>
* <li><code>0</code> single-ASN1-type</li>
* <li><code>1</code> OCTET STRING</li>
* <li><code>2</code> BIT STRING</li>
* </ul>
*/
public int Encoding
{
get
{
return encoding;
}
set
{
if (encoding < 0 || encoding > 2)
throw new InvalidOperationException("invalid encoding value: " + encoding);
this.encoding = value;
}
}
public Asn1Object ExternalContent
{
get { return externalContent; }
set { this.externalContent = value; }
}
public DerInteger IndirectReference
{
get { return indirectReference; }
set { this.indirectReference = value; }
}
private static Asn1Object GetObjFromVector(Asn1EncodableVector v, int index)
{
if (v.Count <= index)
throw new ArgumentException("too few objects in input vector", "v");
return v[index].ToAsn1Object();
}
private static void WriteEncodable(MemoryStream ms, Asn1Encodable e)
{
if (e != null)
{
byte[] bs = e.GetDerEncoded();
ms.Write(bs, 0, bs.Length);
}
}
}
}
using System;
using System.IO;
namespace Org.BouncyCastle.Asn1
{
public class DerExternalParser
: Asn1Encodable
{
private readonly Asn1StreamParser _parser;
public DerExternalParser(Asn1StreamParser parser)
{
this._parser = parser;
}
public IAsn1Convertible ReadObject()
{
return _parser.ReadObject();
}
public override Asn1Object ToAsn1Object()
{
return new DerExternal(_parser.ReadVector());
}
}
}
using System.IO;
using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Asn1
{
public abstract class DerGenerator
: Asn1Generator
{
private bool _tagged = false;
private bool _isExplicit;
private int _tagNo;
protected DerGenerator(
Stream outStream)
: base(outStream)
{
}
protected DerGenerator(
Stream outStream,
int tagNo,
bool isExplicit)
: base(outStream)
{
_tagged = true;
_isExplicit = isExplicit;
_tagNo = tagNo;
}
private static void WriteLength(
Stream outStr,
int length)
{
if (length > 127)
{
int size = 1;
int val = length;
while ((val >>= 8) != 0)
{
size++;
}
outStr.WriteByte((byte)(size | 0x80));
for (int i = (size - 1) * 8; i >= 0; i -= 8)
{
outStr.WriteByte((byte)(length >> i));
}
}
else
{
outStr.WriteByte((byte)length);
}
}
internal static void WriteDerEncoded(
Stream outStream,
int tag,
byte[] bytes)
{
outStream.WriteByte((byte) tag);
WriteLength(outStream, bytes.Length);
outStream.Write(bytes, 0, bytes.Length);
}
internal void WriteDerEncoded(
int tag,
byte[] bytes)
{
if (_tagged)
{
int tagNum = _tagNo | Asn1Tags.Tagged;
if (_isExplicit)
{
int newTag = _tagNo | Asn1Tags.Constructed | Asn1Tags.Tagged;
MemoryStream bOut = new MemoryStream();
WriteDerEncoded(bOut, tag, bytes);
WriteDerEncoded(Out, newTag, bOut.ToArray());
}
else
{
if ((tag & Asn1Tags.Constructed) != 0)
{
tagNum |= Asn1Tags.Constructed;
}
WriteDerEncoded(Out, tagNum, bytes);
}
}
else
{
WriteDerEncoded(Out, tag, bytes);
}
}
internal static void WriteDerEncoded(
Stream outStr,
int tag,
Stream inStr)
{
WriteDerEncoded(outStr, tag, Streams.ReadAll(inStr));
}
}
}
using System;
using System.IO;
using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Asn1
{
public class DerOctetStringParser
: Asn1OctetStringParser
{
private readonly DefiniteLengthInputStream stream;
internal DerOctetStringParser(
DefiniteLengthInputStream stream)
{
this.stream = stream;
}
public Stream GetOctetStream()
{
return stream;
}
public Asn1Object ToAsn1Object()
{
try
{
return new DerOctetString(stream.ToArray());
}
catch (IOException e)
{
throw new InvalidOperationException("IOException converting stream to byte array: " + e.Message, e);
}
}
}
}
using System.IO;
namespace Org.BouncyCastle.Asn1
{
public class DerSequenceGenerator
: DerGenerator
{
private readonly MemoryStream _bOut = new MemoryStream();
public DerSequenceGenerator(
Stream outStream)
: base(outStream)
{
}
public DerSequenceGenerator(
Stream outStream,
int tagNo,
bool isExplicit)
: base(outStream, tagNo, isExplicit)
{
}
public override void AddObject(
Asn1Encodable obj)
{
new DerOutputStream(_bOut).WriteObject(obj);
}
public override Stream GetRawOutputStream()
{
return _bOut;
}
public override void Close()
{
WriteDerEncoded(Asn1Tags.Constructed | Asn1Tags.Sequence, _bOut.ToArray());
}
}
}
namespace Org.BouncyCastle.Asn1
{
public class DerSequenceParser
: Asn1SequenceParser
{
private readonly Asn1StreamParser _parser;
internal DerSequenceParser(
Asn1StreamParser parser)
{
this._parser = parser;
}
public IAsn1Convertible ReadObject()
{
return _parser.ReadObject();
}
public Asn1Object ToAsn1Object()
{
return new DerSequence(_parser.ReadVector());
}
}
}
using System.IO;
namespace Org.BouncyCastle.Asn1
{
public class DerSetGenerator
: DerGenerator
{
private readonly MemoryStream _bOut = new MemoryStream();
public DerSetGenerator(
Stream outStream)
: base(outStream)
{
}
public DerSetGenerator(
Stream outStream,
int tagNo,
bool isExplicit)
: base(outStream, tagNo, isExplicit)
{
}
public override void AddObject(
Asn1Encodable obj)
{
new DerOutputStream(_bOut).WriteObject(obj);
}
public override Stream GetRawOutputStream()
{
return _bOut;
}
public override void Close()
{
WriteDerEncoded(Asn1Tags.Constructed | Asn1Tags.Set, _bOut.ToArray());
}
}
}
namespace Org.BouncyCastle.Asn1
{
public class DerSetParser
: Asn1SetParser
{
private readonly Asn1StreamParser _parser;
internal DerSetParser(
Asn1StreamParser parser)
{
this._parser = parser;
}
public IAsn1Convertible ReadObject()
{
return _parser.ReadObject();
}
public Asn1Object ToAsn1Object()
{
return new DerSet(_parser.ReadVector(), false);
}
}
}
using System;
using System.IO;
using Org.BouncyCastle.Utilities.IO;
namespace Org.BouncyCastle.Asn1
{
class DefiniteLengthInputStream
: LimitedInputStream
{
private static readonly byte[] EmptyBytes = new byte[0];
private readonly int _originalLength;
private int _remaining;
internal DefiniteLengthInputStream(
Stream inStream,
int length)
: base(inStream, length)
{
if (length < 0)
throw new ArgumentException("negative lengths not allowed", "length");
this._originalLength = length;
this._remaining = length;
if (length == 0)
{
SetParentEofDetect(true);
}
}
internal int Remaining
{
get { return _remaining; }
}
public override int ReadByte()
{
if (_remaining == 0)
return -1;
int b = _in.ReadByte();
if (b < 0)
throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
if (--_remaining == 0)
{
SetParentEofDetect(true);
}
return b;
}
public override int Read(
byte[] buf,
int off,
int len)
{
if (_remaining == 0)
return 0;
int toRead = System.Math.Min(len, _remaining);
int numRead = _in.Read(buf, off, toRead);
if (numRead < 1)
throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
if ((_remaining -= numRead) == 0)
{
SetParentEofDetect(true);
}
return numRead;
}
internal void ReadAllIntoByteArray(byte[] buf)
{
if (_remaining != buf.Length)
throw new ArgumentException("buffer length not right for data");
if ((_remaining -= Streams.ReadFully(_in, buf)) != 0)
throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
SetParentEofDetect(true);
}
internal byte[] ToArray()
{
if (_remaining == 0)
return EmptyBytes;
byte[] bytes = new byte[_remaining];
if ((_remaining -= Streams.ReadFully(_in, bytes)) != 0)
throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining);
SetParentEofDetect(true);
return bytes;
}
}
}
using System;
using System.IO;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
/**
* Base class for an application specific object
*/
public class DerApplicationSpecific
: Asn1Object
{
private readonly bool isConstructed;
private readonly int tag;
private readonly byte[] octets;
internal DerApplicationSpecific(
bool isConstructed,
int tag,
byte[] octets)
{
this.isConstructed = isConstructed;
this.tag = tag;
this.octets = octets;
}
public DerApplicationSpecific(
int tag,
byte[] octets)
: this(false, tag, octets)
{
}
public DerApplicationSpecific(
int tag,
Asn1Encodable obj)
: this(true, tag, obj)
{
}
public DerApplicationSpecific(
bool isExplicit,
int tag,
Asn1Encodable obj)
{
Asn1Object asn1Obj = obj.ToAsn1Object();
byte[] data = asn1Obj.GetDerEncoded();
this.isConstructed = Asn1TaggedObject.IsConstructed(isExplicit, asn1Obj);
this.tag = tag;
if (isExplicit)
{
this.octets = data;
}
else
{
int lenBytes = GetLengthOfHeader(data);
byte[] tmp = new byte[data.Length - lenBytes];
Array.Copy(data, lenBytes, tmp, 0, tmp.Length);
this.octets = tmp;
}
}
public DerApplicationSpecific(
int tagNo,
Asn1EncodableVector vec)
{
this.tag = tagNo;
this.isConstructed = true;
MemoryStream bOut = new MemoryStream();
for (int i = 0; i != vec.Count; i++)
{
try
{
byte[] bs = vec[i].GetDerEncoded();
bOut.Write(bs, 0, bs.Length);
}
catch (IOException e)
{
throw new InvalidOperationException("malformed object", e);
}
}
this.octets = bOut.ToArray();
}
private int GetLengthOfHeader(
byte[] data)
{
int length = data[1]; // TODO: assumes 1 byte tag
if (length == 0x80)
{
return 2; // indefinite-length encoding
}
if (length > 127)
{
int size = length & 0x7f;
// Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
if (size > 4)
{
throw new InvalidOperationException("DER length more than 4 bytes: " + size);
}
return size + 2;
}
return 2;
}
public bool IsConstructed()
{
return isConstructed;
}
public byte[] GetContents()
{
return octets;
}
public int ApplicationTag
{
get { return tag; }
}
/**
* Return the enclosed object assuming explicit tagging.
*
* @return the resulting object
* @throws IOException if reconstruction fails.
*/
public Asn1Object GetObject()
{
return FromByteArray(GetContents());
}
/**
* Return the enclosed object assuming implicit tagging.
*
* @param derTagNo the type tag that should be applied to the object's contents.
* @return the resulting object
* @throws IOException if reconstruction fails.
*/
public Asn1Object GetObject(
int derTagNo)
{
if (derTagNo >= 0x1f)
throw new IOException("unsupported tag number");
byte[] orig = this.GetEncoded();
byte[] tmp = ReplaceTagNumber(derTagNo, orig);
if ((orig[0] & Asn1Tags.Constructed) != 0)
{
tmp[0] |= Asn1Tags.Constructed;
}
return FromByteArray(tmp);
}
internal override void Encode(
DerOutputStream derOut)
{
int classBits = Asn1Tags.Application;
if (isConstructed)
{
classBits |= Asn1Tags.Constructed;
}
derOut.WriteEncoded(classBits, tag, octets);
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerApplicationSpecific other = asn1Object as DerApplicationSpecific;
if (other == null)
return false;
return this.isConstructed == other.isConstructed
&& this.tag == other.tag
&& Arrays.AreEqual(this.octets, other.octets);
}
protected override int Asn1GetHashCode()
{
return isConstructed.GetHashCode() ^ tag.GetHashCode() ^ Arrays.GetHashCode(octets);
}
private byte[] ReplaceTagNumber(
int newTag,
byte[] input)
{
int tagNo = input[0] & 0x1f;
int index = 1;
//
// with tagged object tag number is bottom 5 bits, or stored at the start of the content
//
if (tagNo == 0x1f)
{
tagNo = 0;
int b = input[index++] & 0xff;
// X.690-0207 8.1.2.4.2
// "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
if ((b & 0x7f) == 0) // Note: -1 will pass
{
throw new InvalidOperationException("corrupted stream - invalid high tag number found");
}
while ((b >= 0) && ((b & 0x80) != 0))
{
tagNo |= (b & 0x7f);
tagNo <<= 7;
b = input[index++] & 0xff;
}
tagNo |= (b & 0x7f);
}
byte[] tmp = new byte[input.Length - index + 1];
Array.Copy(input, index, tmp, 1, tmp.Length - 1);
tmp[0] = (byte)newTag;
return tmp;
}
}
}
using System;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
/**
* Der BMPString object.
*/
public class DerBmpString
: DerStringBase
{
private readonly string str;
/**
* return a BMP string from the given object.
*
* @param obj the object we want converted.
* @exception ArgumentException if the object cannot be converted.
*/
public static DerBmpString GetInstance(
object obj)
{
if (obj == null || obj is DerBmpString)
{
return (DerBmpString)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return a BMP string from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerBmpString GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerBmpString)
{
return GetInstance(o);
}
return new DerBmpString(Asn1OctetString.GetInstance(o).GetOctets());
}
/**
* basic constructor - byte encoded string.
*/
public DerBmpString(
byte[] str)
{
if (str == null)
throw new ArgumentNullException("str");
char[] cs = new char[str.Length / 2];
for (int i = 0; i != cs.Length; i++)
{
cs[i] = (char)((str[2 * i] << 8) | (str[2 * i + 1] & 0xff));
}
this.str = new string(cs);
}
/**
* basic constructor
*/
public DerBmpString(
string str)
{
if (str == null)
throw new ArgumentNullException("str");
this.str = str;
}
public override string GetString()
{
return str;
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerBmpString other = asn1Object as DerBmpString;
if (other == null)
return false;
return this.str.Equals(other.str);
}
internal override void Encode(
DerOutputStream derOut)
{
char[] c = str.ToCharArray();
byte[] b = new byte[c.Length * 2];
for (int i = 0; i != c.Length; i++)
{
b[2 * i] = (byte)(c[i] >> 8);
b[2 * i + 1] = (byte)c[i];
}
derOut.WriteEncoded(Asn1Tags.BmpString, b);
}
}
}
using System;
using System.Diagnostics;
using System.Text;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
public class DerBitString
: DerStringBase
{
private static readonly char[] table
= { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
protected readonly byte[] mData;
protected readonly int mPadBits;
/**
* return a Bit string from the passed in object
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerBitString GetInstance(
object obj)
{
if (obj == null || obj is DerBitString)
{
return (DerBitString) obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return a Bit string from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerBitString GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerBitString)
{
return GetInstance(o);
}
return FromAsn1Octets(((Asn1OctetString)o).GetOctets());
}
/**
* @param data the octets making up the bit string.
* @param padBits the number of extra bits at the end of the string.
*/
public DerBitString(
byte[] data,
int padBits)
{
if (data == null)
throw new ArgumentNullException("data");
if (padBits < 0 || padBits > 7)
throw new ArgumentException("must be in the range 0 to 7", "padBits");
if (data.Length == 0 && padBits != 0)
throw new ArgumentException("if 'data' is empty, 'padBits' must be 0");
this.mData = Arrays.Clone(data);
this.mPadBits = padBits;
}
public DerBitString(
byte[] data)
: this(data, 0)
{
}
public DerBitString(
int namedBits)
{
if (namedBits == 0)
{
this.mData = new byte[0];
this.mPadBits = 0;
return;
}
int bits = BigInteger.BitLen(namedBits);
int bytes = (bits + 7) / 8;
Debug.Assert(0 < bytes && bytes <= 4);
byte[] data = new byte[bytes];
--bytes;
for (int i = 0; i < bytes; i++)
{
data[i] = (byte)namedBits;
namedBits >>= 8;
}
Debug.Assert((namedBits & 0xFF) != 0);
data[bytes] = (byte)namedBits;
int padBits = 0;
while ((namedBits & (1 << padBits)) == 0)
{
++padBits;
}
Debug.Assert(padBits < 8);
this.mData = data;
this.mPadBits = padBits;
}
public DerBitString(
Asn1Encodable obj)
: this(obj.GetDerEncoded())
{
}
/**
* Return the octets contained in this BIT STRING, checking that this BIT STRING really
* does represent an octet aligned string. Only use this method when the standard you are
* following dictates that the BIT STRING will be octet aligned.
*
* @return a copy of the octet aligned data.
*/
public virtual byte[] GetOctets()
{
if (mPadBits != 0)
throw new InvalidOperationException("attempt to get non-octet aligned data from BIT STRING");
return Arrays.Clone(mData);
}
public virtual byte[] GetBytes()
{
byte[] data = Arrays.Clone(mData);
// DER requires pad bits be zero
if (mPadBits > 0)
{
data[data.Length - 1] &= (byte)(0xFF << mPadBits);
}
return data;
}
public virtual int PadBits
{
get { return mPadBits; }
}
/**
* @return the value of the bit string as an int (truncating if necessary)
*/
public virtual int IntValue
{
get
{
int value = 0, length = System.Math.Min(4, mData.Length);
for (int i = 0; i < length; ++i)
{
value |= (int)mData[i] << (8 * i);
}
if (mPadBits > 0 && length == mData.Length)
{
int mask = (1 << mPadBits) - 1;
value &= ~(mask << (8 * (length - 1)));
}
return value;
}
}
internal override void Encode(
DerOutputStream derOut)
{
if (mPadBits > 0)
{
int last = mData[mData.Length - 1];
int mask = (1 << mPadBits) - 1;
int unusedBits = last & mask;
if (unusedBits != 0)
{
byte[] contents = Arrays.Prepend(mData, (byte)mPadBits);
/*
* X.690-0207 11.2.1: Each unused bit in the final octet of the encoding of a bit string value shall be set to zero.
*/
contents[contents.Length - 1] = (byte)(last ^ unusedBits);
derOut.WriteEncoded(Asn1Tags.BitString, contents);
return;
}
}
derOut.WriteEncoded(Asn1Tags.BitString, (byte)mPadBits, mData);
}
protected override int Asn1GetHashCode()
{
return mPadBits.GetHashCode() ^ Arrays.GetHashCode(mData);
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerBitString other = asn1Object as DerBitString;
if (other == null)
return false;
return this.mPadBits == other.mPadBits
&& Arrays.AreEqual(this.mData, other.mData);
}
public override string GetString()
{
StringBuilder buffer = new StringBuilder("#");
byte[] str = GetDerEncoded();
for (int i = 0; i != str.Length; i++)
{
uint ubyte = str[i];
buffer.Append(table[(ubyte >> 4) & 0xf]);
buffer.Append(table[str[i] & 0xf]);
}
return buffer.ToString();
}
internal static DerBitString FromAsn1Octets(byte[] octets)
{
if (octets.Length < 1)
throw new ArgumentException("truncated BIT STRING detected", "octets");
int padBits = octets[0];
byte[] data = Arrays.CopyOfRange(octets, 1, octets.Length);
if (padBits > 0 && padBits < 8 && data.Length > 0)
{
int last = data[data.Length - 1];
int mask = (1 << padBits) - 1;
if ((last & mask) != 0)
{
return new BerBitString(data, padBits);
}
}
return new DerBitString(data, padBits);
}
}
}
using System;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
public class DerBoolean
: Asn1Object
{
private readonly byte value;
public static readonly DerBoolean False = new DerBoolean(false);
public static readonly DerBoolean True = new DerBoolean(true);
/**
* return a bool from the passed in object.
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerBoolean GetInstance(
object obj)
{
if (obj == null || obj is DerBoolean)
{
return (DerBoolean) obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return a DerBoolean from the passed in bool.
*/
public static DerBoolean GetInstance(
bool value)
{
return value ? True : False;
}
/**
* return a Boolean from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerBoolean GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerBoolean)
{
return GetInstance(o);
}
return FromOctetString(((Asn1OctetString)o).GetOctets());
}
public DerBoolean(
byte[] val)
{
if (val.Length != 1)
throw new ArgumentException("byte value should have 1 byte in it", "val");
// TODO Are there any constraints on the possible byte values?
this.value = val[0];
}
private DerBoolean(
bool value)
{
this.value = value ? (byte)0xff : (byte)0;
}
public bool IsTrue
{
get { return value != 0; }
}
internal override void Encode(
DerOutputStream derOut)
{
// TODO Should we make sure the byte value is one of '0' or '0xff' here?
derOut.WriteEncoded(Asn1Tags.Boolean, new byte[]{ value });
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerBoolean other = asn1Object as DerBoolean;
if (other == null)
return false;
return IsTrue == other.IsTrue;
}
protected override int Asn1GetHashCode()
{
return IsTrue.GetHashCode();
}
public override string ToString()
{
return IsTrue ? "TRUE" : "FALSE";
}
internal static DerBoolean FromOctetString(byte[] value)
{
if (value.Length != 1)
{
throw new ArgumentException("BOOLEAN value should have 1 byte in it", "value");
}
byte b = value[0];
return b == 0 ? False : b == 0xFF ? True : new DerBoolean(value);
}
}
}
using System;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
public class DerEnumerated
: Asn1Object
{
private readonly byte[] bytes;
/**
* return an integer from the passed in object
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerEnumerated GetInstance(
object obj)
{
if (obj == null || obj is DerEnumerated)
{
return (DerEnumerated)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return an Enumerated from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerEnumerated GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerEnumerated)
{
return GetInstance(o);
}
return FromOctetString(((Asn1OctetString)o).GetOctets());
}
public DerEnumerated(
int val)
{
bytes = BigInteger.ValueOf(val).ToByteArray();
}
public DerEnumerated(
BigInteger val)
{
bytes = val.ToByteArray();
}
public DerEnumerated(
byte[] bytes)
{
this.bytes = bytes;
}
public BigInteger Value
{
get { return new BigInteger(bytes); }
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.Enumerated, bytes);
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerEnumerated other = asn1Object as DerEnumerated;
if (other == null)
return false;
return Arrays.AreEqual(this.bytes, other.bytes);
}
protected override int Asn1GetHashCode()
{
return Arrays.GetHashCode(bytes);
}
private static readonly DerEnumerated[] cache = new DerEnumerated[12];
internal static DerEnumerated FromOctetString(byte[] enc)
{
if (enc.Length == 0)
{
throw new ArgumentException("ENUMERATED has zero length", "enc");
}
if (enc.Length == 1)
{
int value = enc[0];
if (value < cache.Length)
{
DerEnumerated cached = cache[value];
if (cached != null)
{
return cached;
}
return cache[value] = new DerEnumerated(Arrays.Clone(enc));
}
}
return new DerEnumerated(Arrays.Clone(enc));
}
}
}
using System;
using System.Text;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
public class DerGeneralString
: DerStringBase
{
private readonly string str;
public static DerGeneralString GetInstance(
object obj)
{
if (obj == null || obj is DerGeneralString)
{
return (DerGeneralString) obj;
}
throw new ArgumentException("illegal object in GetInstance: "
+ Platform.GetTypeName(obj));
}
public static DerGeneralString GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerGeneralString)
{
return GetInstance(o);
}
return new DerGeneralString(((Asn1OctetString)o).GetOctets());
}
public DerGeneralString(
byte[] str)
: this(Strings.FromAsciiByteArray(str))
{
}
public DerGeneralString(
string str)
{
if (str == null)
throw new ArgumentNullException("str");
this.str = str;
}
public override string GetString()
{
return str;
}
public byte[] GetOctets()
{
return Strings.ToAsciiByteArray(str);
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.GeneralString, GetOctets());
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerGeneralString other = asn1Object as DerGeneralString;
if (other == null)
return false;
return this.str.Equals(other.str);
}
}
}
using System;
using System.Globalization;
using System.Text;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
/**
* Generalized time object.
*/
public class DerGeneralizedTime
: Asn1Object
{
private readonly string time;
/**
* return a generalized time from the passed in object
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerGeneralizedTime GetInstance(
object obj)
{
if (obj == null || obj is DerGeneralizedTime)
{
return (DerGeneralizedTime)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
/**
* return a Generalized Time object from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerGeneralizedTime GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerGeneralizedTime)
{
return GetInstance(o);
}
return new DerGeneralizedTime(((Asn1OctetString)o).GetOctets());
}
/**
* The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z
* for local time, or Z+-HHMM on the end, for difference between local
* time and UTC time. The fractional second amount f must consist of at
* least one number with trailing zeroes removed.
*
* @param time the time string.
* @exception ArgumentException if string is an illegal format.
*/
public DerGeneralizedTime(
string time)
{
this.time = time;
try
{
ToDateTime();
}
catch (FormatException e)
{
throw new ArgumentException("invalid date string: " + e.Message);
}
}
/**
* base constructor from a local time object
*/
public DerGeneralizedTime(
DateTime time)
{
#if PORTABLE
this.time = time.ToUniversalTime().ToString(@"yyyyMMddHHmmss\Z");
#else
this.time = time.ToString(@"yyyyMMddHHmmss\Z");
#endif
}
internal DerGeneralizedTime(
byte[] bytes)
{
//
// explicitly convert to characters
//
this.time = Strings.FromAsciiByteArray(bytes);
}
/**
* Return the time.
* @return The time string as it appeared in the encoded object.
*/
public string TimeString
{
get { return time; }
}
/**
* return the time - always in the form of
* YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm).
* <p>
* Normally in a certificate we would expect "Z" rather than "GMT",
* however adding the "GMT" means we can just use:
* <pre>
* dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
* </pre>
* To read in the time and Get a date which is compatible with our local
* time zone.</p>
*/
public string GetTime()
{
//
// standardise the format.
//
if (time[time.Length - 1] == 'Z')
{
return time.Substring(0, time.Length - 1) + "GMT+00:00";
}
else
{
int signPos = time.Length - 5;
char sign = time[signPos];
if (sign == '-' || sign == '+')
{
return time.Substring(0, signPos)
+ "GMT"
+ time.Substring(signPos, 3)
+ ":"
+ time.Substring(signPos + 3);
}
else
{
signPos = time.Length - 3;
sign = time[signPos];
if (sign == '-' || sign == '+')
{
return time.Substring(0, signPos)
+ "GMT"
+ time.Substring(signPos)
+ ":00";
}
}
}
return time + CalculateGmtOffset();
}
private string CalculateGmtOffset()
{
char sign = '+';
DateTime time = ToDateTime();
#if SILVERLIGHT || PORTABLE
long offset = time.Ticks - time.ToUniversalTime().Ticks;
if (offset < 0)
{
sign = '-';
offset = -offset;
}
int hours = (int)(offset / TimeSpan.TicksPerHour);
int minutes = (int)(offset / TimeSpan.TicksPerMinute) % 60;
#else
// Note: GetUtcOffset incorporates Daylight Savings offset
TimeSpan offset = TimeZone.CurrentTimeZone.GetUtcOffset(time);
if (offset.CompareTo(TimeSpan.Zero) < 0)
{
sign = '-';
offset = offset.Duration();
}
int hours = offset.Hours;
int minutes = offset.Minutes;
#endif
return "GMT" + sign + Convert(hours) + ":" + Convert(minutes);
}
private static string Convert(
int time)
{
if (time < 10)
{
return "0" + time;
}
return time.ToString();
}
public DateTime ToDateTime()
{
string formatStr;
string d = time;
bool makeUniversal = false;
if (Platform.EndsWith(d, "Z"))
{
if (HasFractionalSeconds)
{
int fCount = d.Length - d.IndexOf('.') - 2;
formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"\Z";
}
else
{
formatStr = @"yyyyMMddHHmmss\Z";
}
}
else if (time.IndexOf('-') > 0 || time.IndexOf('+') > 0)
{
d = GetTime();
makeUniversal = true;
if (HasFractionalSeconds)
{
int fCount = Platform.IndexOf(d, "GMT") - 1 - d.IndexOf('.');
formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"'GMT'zzz";
}
else
{
formatStr = @"yyyyMMddHHmmss'GMT'zzz";
}
}
else
{
if (HasFractionalSeconds)
{
int fCount = d.Length - 1 - d.IndexOf('.');
formatStr = @"yyyyMMddHHmmss." + FString(fCount);
}
else
{
formatStr = @"yyyyMMddHHmmss";
}
// TODO?
// dateF.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID()));
}
return ParseDateString(d, formatStr, makeUniversal);
}
private string FString(
int count)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; ++i)
{
sb.Append('f');
}
return sb.ToString();
}
private DateTime ParseDateString(string s, string format, bool makeUniversal)
{
/*
* NOTE: DateTime.Kind and DateTimeStyles.AssumeUniversal not available in .NET 1.1
*/
DateTimeStyles style = DateTimeStyles.None;
if (Platform.EndsWith(format, "Z"))
{
try
{
style = (DateTimeStyles)Enums.GetEnumValue(typeof(DateTimeStyles), "AssumeUniversal");
}
catch (Exception)
{
}
style |= DateTimeStyles.AdjustToUniversal;
}
DateTime dt = DateTime.ParseExact(s, format, DateTimeFormatInfo.InvariantInfo, style);
return makeUniversal ? dt.ToUniversalTime() : dt;
}
private bool HasFractionalSeconds
{
get { return time.IndexOf('.') == 14; }
}
private byte[] GetOctets()
{
return Strings.ToAsciiByteArray(time);
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.GeneralizedTime, GetOctets());
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerGeneralizedTime other = asn1Object as DerGeneralizedTime;
if (other == null)
return false;
return this.time.Equals(other.time);
}
protected override int Asn1GetHashCode()
{
return time.GetHashCode();
}
}
}
using System;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
public class DerGraphicString
: DerStringBase
{
private readonly byte[] mString;
/**
* return a Graphic String from the passed in object
*
* @param obj a DerGraphicString or an object that can be converted into one.
* @exception IllegalArgumentException if the object cannot be converted.
* @return a DerGraphicString instance, or null.
*/
public static DerGraphicString GetInstance(object obj)
{
if (obj == null || obj is DerGraphicString)
{
return (DerGraphicString)obj;
}
if (obj is byte[])
{
try
{
return (DerGraphicString)FromByteArray((byte[])obj);
}
catch (Exception e)
{
throw new ArgumentException("encoding error in GetInstance: " + e.ToString(), "obj");
}
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj");
}
/**
* return a Graphic String from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return a DerGraphicString instance, or null.
*/
public static DerGraphicString GetInstance(Asn1TaggedObject obj, bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerGraphicString)
{
return GetInstance(o);
}
return new DerGraphicString(((Asn1OctetString)o).GetOctets());
}
/**
* basic constructor - with bytes.
* @param string the byte encoding of the characters making up the string.
*/
public DerGraphicString(byte[] encoding)
{
this.mString = Arrays.Clone(encoding);
}
public override string GetString()
{
return Strings.FromByteArray(mString);
}
public byte[] GetOctets()
{
return Arrays.Clone(mString);
}
internal override void Encode(DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.GraphicString, mString);
}
protected override int Asn1GetHashCode()
{
return Arrays.GetHashCode(mString);
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerGraphicString other = asn1Object as DerGraphicString;
if (other == null)
return false;
return Arrays.AreEqual(mString, other.mString);
}
}
}
using System;
using System.Text;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
/**
* Der IA5String object - this is an ascii string.
*/
public class DerIA5String
: DerStringBase
{
private readonly string str;
/**
* return a IA5 string from the passed in object
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerIA5String GetInstance(
object obj)
{
if (obj == null || obj is DerIA5String)
{
return (DerIA5String)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj));
}
/**
* return an IA5 string from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerIA5String GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerIA5String)
{
return GetInstance(o);
}
return new DerIA5String(((Asn1OctetString)o).GetOctets());
}
/**
* basic constructor - with bytes.
*/
public DerIA5String(
byte[] str)
: this(Strings.FromAsciiByteArray(str), false)
{
}
/**
* basic constructor - without validation.
*/
public DerIA5String(
string str)
: this(str, false)
{
}
/**
* Constructor with optional validation.
*
* @param string the base string to wrap.
* @param validate whether or not to check the string.
* @throws ArgumentException if validate is true and the string
* contains characters that should not be in an IA5String.
*/
public DerIA5String(
string str,
bool validate)
{
if (str == null)
throw new ArgumentNullException("str");
if (validate && !IsIA5String(str))
throw new ArgumentException("string contains illegal characters", "str");
this.str = str;
}
public override string GetString()
{
return str;
}
public byte[] GetOctets()
{
return Strings.ToAsciiByteArray(str);
}
internal override void Encode(
DerOutputStream derOut)
{
derOut.WriteEncoded(Asn1Tags.IA5String, GetOctets());
}
protected override int Asn1GetHashCode()
{
return this.str.GetHashCode();
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerIA5String other = asn1Object as DerIA5String;
if (other == null)
return false;
return this.str.Equals(other.str);
}
/**
* return true if the passed in String can be represented without
* loss as an IA5String, false otherwise.
*
* @return true if in printable set, false otherwise.
*/
public static bool IsIA5String(
string str)
{
foreach (char ch in str)
{
if (ch > 0x007f)
{
return false;
}
}
return true;
}
}
}