Skip to content

Commit 7aa0591

Browse files
committed
added new Asn1RelativeOid class
1 parent f447c6e commit 7aa0591

1 file changed

Lines changed: 109 additions & 0 deletions

File tree

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Numerics;
5+
using System.Text;
6+
using SysadminsLV.Asn1Parser.Utils;
7+
8+
namespace SysadminsLV.Asn1Parser.Universal;
9+
/// <summary>
10+
/// Represents ASN.1 RELATIVE-OID type.
11+
/// </summary>
12+
public class Asn1RelativeOid : Asn1Universal {
13+
const Asn1Type TYPE = Asn1Type.RELATIVE_OID;
14+
15+
/// <summary>
16+
/// Initializes a new instance of the <strong>Asn1RelativeOid</strong> class from an existing
17+
/// <see cref="Asn1Reader"/> class instance.
18+
/// </summary>
19+
/// <param name="asn"><see cref="Asn1Reader"/> object in the position that represents relative object identifier.</param>
20+
/// <exception cref="Asn1InvalidTagException">
21+
/// The current state of <strong>ASN1</strong> object is not relative object identifier.
22+
/// </exception>
23+
public Asn1RelativeOid(Asn1Reader asn) : base(asn, TYPE) {
24+
Value = decode(asn);
25+
}
26+
/// <summary>
27+
/// Initializes a new instance of the <strong>Asn1RelativeOid</strong> class from a byte array
28+
/// that represents encoded relative object identifier.
29+
/// </summary>
30+
/// <param name="rawData">Byte array that represents encoded relative object identifier.</param>
31+
public Asn1RelativeOid(Byte[] rawData) : this(new Asn1Reader(rawData)) { }
32+
/// <summary>
33+
/// Initializes a new instance of the <strong>Asn1RelativeOid</strong> class from a string
34+
/// that represents relative object identifier value.
35+
/// </summary>
36+
/// <param name="relativeOid">
37+
/// String that represents relative object identifier value. This parameter accepts relative OIDs with or without
38+
/// leading dot, e.g. '5', '.5', '5.10', '.5.10'.
39+
/// </param>
40+
/// <exception cref="ArgumentNullException"><strong>relativeOid</strong> parameter is null.</exception>
41+
/// <exception cref="OverflowException">The string is too large.</exception>
42+
/// <remarks>Maximum relative object identifier string is 8kb.</remarks>
43+
public Asn1RelativeOid(String relativeOid) : base(TYPE) {
44+
if (relativeOid == null) {
45+
throw new ArgumentNullException(nameof(relativeOid));
46+
}
47+
m_encode(relativeOid);
48+
if (relativeOid.StartsWith(".")) {
49+
Value = relativeOid;
50+
} else {
51+
Value = "." + relativeOid;
52+
}
53+
}
54+
55+
/// <summary>
56+
/// Gets relative OID value string with leading dot (e.g. '.1', '.1.3').
57+
/// </summary>
58+
public String Value { get; private set; }
59+
60+
void m_encode(String oidString) {
61+
if (String.IsNullOrWhiteSpace(oidString)) {
62+
Initialize(new Asn1Reader([Tag, 0]));
63+
Value = String.Empty;
64+
return;
65+
}
66+
oidString = oidString.Trim();
67+
if (oidString.Length > 8096) {
68+
throw new OverflowException("Oid string is longer than 8kb");
69+
}
70+
IEnumerable<BigInteger> tokens = oidString
71+
.Split(['.'], StringSplitOptions.RemoveEmptyEntries)
72+
.Select(BigInteger.Parse);
73+
Initialize(new Asn1Reader(Asn1Utils.Encode(encode(tokens), TYPE)));
74+
}
75+
static Byte[] encode(IEnumerable<BigInteger> tokens) {
76+
var rawOid = new List<Byte>();
77+
foreach (BigInteger token in tokens) {
78+
rawOid.AddRange(OidUtils.EncodeOidArc(token));
79+
}
80+
81+
return rawOid.ToArray();
82+
}
83+
static String decode(Asn1Reader asn) {
84+
var SB = new StringBuilder();
85+
for (Int32 i = 0; i < asn.PayloadLength; i++) {
86+
Int32 pi = asn.PayloadStartOffset + i;
87+
88+
BigInteger value = 0;
89+
Boolean proceed;
90+
do {
91+
value <<= 7;
92+
value += asn[pi] & 0x7f;
93+
proceed = (asn[pi] & 0x80) > 0;
94+
if (proceed) {
95+
i++;
96+
pi++;
97+
}
98+
} while (proceed);
99+
100+
SB.Append("." + value);
101+
}
102+
return SB.ToString();
103+
}
104+
105+
/// <inheritdoc />
106+
public override String GetDisplayValue() {
107+
return Value;
108+
}
109+
}

0 commit comments

Comments
 (0)