Difference between revisions of "Unit ASN.1"
From Ultibo.org
(4 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
---- | ---- | ||
− | '''Ultibo ASN.1 | + | '''Ultibo ASN.1 Interface unit''' |
Abstract Syntax Notation One (ASN.1) is an interface description language for defining data structures that can be serialized and deserialized in a standard, cross-platform way. It's broadly used in telecommunications and computer networking, and especially in cryptography. | Abstract Syntax Notation One (ASN.1) is an interface description language for defining data structures that can be serialized and deserialized in a standard, cross-platform way. It's broadly used in telecommunications and computer networking, and especially in cryptography. | ||
Line 16: | Line 16: | ||
---- | ---- | ||
− | '' | + | |
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ASN1 specific constants''' <code> ASN1_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ASN1_TAG_EOC = $00;</code> | ||
+ | | Not used with DER | ||
+ | |- | ||
+ | | <code>ASN1_TAG_BOOLEAN = $01;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_TAG_INTEGER = $02;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_TAG_BITSTRING = $03;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_TAG_OCTETSTRING = $04;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_TAG_NULL = $05;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_TAG_OID = $06;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_TAG_OBJECT_DESCRIPTOR = $07;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | | <code>ASN1_TAG_EXTERNAL = $08;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | | <code>ASN1_TAG_REAL = $09;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | | <code>ASN1_TAG_ENUMERATED = $0A;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | | <code>ASN1_TAG_EMBEDDED_PDV = $0B;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | | <code>ASN1_TAG_UTF8STRING = $0C;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | | <code>ANS1_TAG_RELATIVE_OID = $0D;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_TAG_SEQUENCE = $10;</code> | ||
+ | | Constructed | ||
+ | |- | ||
+ | | <code>ASN1_TAG_SET = $11;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_TAG_NUMERICSTRING = $12;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | | <code>ASN1_TAG_PRINTABLESTRING = $13;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_TAG_TG1STRING = $14;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | | <code>ASN1_TAG_VIDEOTEXSTRING = $15;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | | <code>ASN1_TAG_IA5STRING = $16;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_TAG_UTCTIME = $17;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_TAG_GENERALIZEDTIME = $18;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | | <code>ASN1_TAG_GRAPHICSTRING = $19;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | | <code>ASN1_TAG_VISIBLESTRING = $1A;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_TAG_GENERALSTRING = $1B;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | | <code>ASN1_TAG_UNIVERSALSTRING = $1C;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | | <code>ASN1_TAG_CHARACTERSTRING = $1D;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | | <code>ASN1_TAG_BMPSTRING = $1E;</code> | ||
+ | | Not supported | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ASN1_TAG_LONGFORM = $1F;</code> | ||
+ | | Tag is encoded in long form | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ASN1_CLASS_UNIVERSAL = 0;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_CLASS_APPLICATION = 1;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_CLASS_CONTEXT_SPECIFIC = 2;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ASN1_CLASS_PRIVATE = 3;</code> | ||
+ | | | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ASN1_MAX_OID_LEN = 20;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
=== Type definitions === | === Type definitions === | ||
---- | ---- | ||
− | '' | + | |
+ | '''ASN1 tag''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PASN1Tag = ^TASN1Tag;</code> | ||
+ | |||
+ | <code>TASN1Tag = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>TagNumber:LongWord;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | | <code>TagClass:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>Length:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>Constructed:Boolean;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>Contents:PByte;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | |||
+ | '''ASN1 OID''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PASN1OID = ^TASN1OID;</code> | ||
+ | |||
+ | <code>TASN1OID = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>Len:Integer;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | | <code>OID:array[0..ASN1_MAX_OID_LEN - 1] of LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
=== Public variables === | === Public variables === | ||
Line 31: | Line 195: | ||
---- | ---- | ||
− | |||
+ | '''ASN1 functions''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function ASN1GetTag(Buffer:PByte; Len:Integer; var Tag:TASN1Tag):Boolean;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' To be documented</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function ASN1ParseOID(Buffer:PByte; Len:Integer; var OID:TASN1OID):Boolean;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Parse an OID value from the buffer</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function ASN1GetOID(Buffer:PByte; Len:Integer; var OID:TASN1OID; var Next:PByte):Boolean;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Read the next ASN1 tag from buffer and decode it as an OID value</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function ASN1GetNull(Buffer:PByte; Len:Integer; var Next:PByte):Boolean;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Read the next ASN1 tag from buffer and decode it as a null value</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function ASN1ParseInt(Buffer:PByte; Len:Integer; var Value:Integer):Boolean;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Parse an integer value from the buffer</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function ASN1ParseBigInt(Buffer:PByte; Len:Integer; var Value:PByte; var Size:Integer):Boolean;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Parse a big integer value from the buffer (Does not include the leading negative byte if present)</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | Memory allocated for Value must be freed by the caller when no longer required | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function ASN1GetInt(Buffer:PByte; Len:Integer; var Value:Integer; var Next:PByte):Boolean;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Read the next ASN1 tag from buffer and decode it as an integer value</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function ASN1ParseBoolean(Buffer:PByte; Len:Integer; var Value:Boolean):Boolean;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Parse a boolean value from the buffer</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function ASN1GetBoolean(Buffer:PByte; Len:Integer; var Value:Boolean; var Next:PByte):Boolean;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Read the next ASN1 tag from buffer and decode it as a boolean value</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | |||
+ | '''ASN1 helper functions''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function ASN1OIDEqual(const OID1,OID2:TASN1OID):Boolean;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' To be documented</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function ASN1OIDEqualPrefix(const OIDPrefix,OID:TASN1OID):Boolean;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' To be documented</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function ASN1OIDToString(const OID:TASN1OID):String;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' To be documented</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function ASN1BitStringToLongWord(Buffer:PByte; Len:Integer):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' To be documented</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
Return to [[Unit_Reference|Unit Reference]] | Return to [[Unit_Reference|Unit Reference]] |
Latest revision as of 04:38, 31 August 2021
Return to Unit Reference
Description
Ultibo ASN.1 Interface unit
Abstract Syntax Notation One (ASN.1) is an interface description language for defining data structures that can be serialized and deserialized in a standard, cross-platform way. It's broadly used in telecommunications and computer networking, and especially in cryptography.
This unit currently only provides the basic functionality required by X509 to read and parse a certificate in DER format.
It is expected that this unit will be expanded to incorporate additional functions over time.
Constants
ASN1 specific constants
ASN1_*
ASN1_TAG_EOC = $00;
|
Not used with DER |
ASN1_TAG_BOOLEAN = $01;
|
|
ASN1_TAG_INTEGER = $02;
|
|
ASN1_TAG_BITSTRING = $03;
|
|
ASN1_TAG_OCTETSTRING = $04;
|
|
ASN1_TAG_NULL = $05;
|
|
ASN1_TAG_OID = $06;
|
|
ASN1_TAG_OBJECT_DESCRIPTOR = $07;
|
Not supported |
ASN1_TAG_EXTERNAL = $08;
|
Not supported |
ASN1_TAG_REAL = $09;
|
Not supported |
ASN1_TAG_ENUMERATED = $0A;
|
Not supported |
ASN1_TAG_EMBEDDED_PDV = $0B;
|
Not supported |
ASN1_TAG_UTF8STRING = $0C;
|
Not supported |
ANS1_TAG_RELATIVE_OID = $0D;
|
|
ASN1_TAG_SEQUENCE = $10;
|
Constructed |
ASN1_TAG_SET = $11;
|
|
ASN1_TAG_NUMERICSTRING = $12;
|
Not supported |
ASN1_TAG_PRINTABLESTRING = $13;
|
|
ASN1_TAG_TG1STRING = $14;
|
Not supported |
ASN1_TAG_VIDEOTEXSTRING = $15;
|
Not supported |
ASN1_TAG_IA5STRING = $16;
|
|
ASN1_TAG_UTCTIME = $17;
|
|
ASN1_TAG_GENERALIZEDTIME = $18;
|
Not supported |
ASN1_TAG_GRAPHICSTRING = $19;
|
Not supported |
ASN1_TAG_VISIBLESTRING = $1A;
|
|
ASN1_TAG_GENERALSTRING = $1B;
|
Not supported |
ASN1_TAG_UNIVERSALSTRING = $1C;
|
Not supported |
ASN1_TAG_CHARACTERSTRING = $1D;
|
Not supported |
ASN1_TAG_BMPSTRING = $1E;
|
Not supported |
ASN1_TAG_LONGFORM = $1F;
|
Tag is encoded in long form |
ASN1_CLASS_UNIVERSAL = 0;
|
|
ASN1_CLASS_APPLICATION = 1;
|
|
ASN1_CLASS_CONTEXT_SPECIFIC = 2;
|
|
ASN1_CLASS_PRIVATE = 3;
|
|
ASN1_MAX_OID_LEN = 20;
|
Type definitions
ASN1 tag
PASN1Tag = ^TASN1Tag;
TASN1Tag = record
TagNumber:LongWord;
|
|
TagClass:LongWord;
|
|
Length:LongWord;
|
|
Constructed:Boolean;
|
|
Contents:PByte;
|
ASN1 OID
PASN1OID = ^TASN1OID;
TASN1OID = record
Len:Integer;
|
|
OID:array[0..ASN1_MAX_OID_LEN - 1] of LongWord;
|
Public variables
None defined
Function declarations
ASN1 functions
function ASN1GetTag(Buffer:PByte; Len:Integer; var Tag:TASN1Tag):Boolean;
Description: To be documented
Note | None documented |
---|
function ASN1ParseOID(Buffer:PByte; Len:Integer; var OID:TASN1OID):Boolean;
Description: Parse an OID value from the buffer
Note | None documented |
---|
function ASN1GetOID(Buffer:PByte; Len:Integer; var OID:TASN1OID; var Next:PByte):Boolean;
Description: Read the next ASN1 tag from buffer and decode it as an OID value
Note | None documented |
---|
function ASN1GetNull(Buffer:PByte; Len:Integer; var Next:PByte):Boolean;
Description: Read the next ASN1 tag from buffer and decode it as a null value
Note | None documented |
---|
function ASN1ParseInt(Buffer:PByte; Len:Integer; var Value:Integer):Boolean;
Description: Parse an integer value from the buffer
Note | None documented |
---|
function ASN1ParseBigInt(Buffer:PByte; Len:Integer; var Value:PByte; var Size:Integer):Boolean;
Description: Parse a big integer value from the buffer (Does not include the leading negative byte if present)
Note | Memory allocated for Value must be freed by the caller when no longer required |
---|
function ASN1GetInt(Buffer:PByte; Len:Integer; var Value:Integer; var Next:PByte):Boolean;
Description: Read the next ASN1 tag from buffer and decode it as an integer value
Note | None documented |
---|
function ASN1ParseBoolean(Buffer:PByte; Len:Integer; var Value:Boolean):Boolean;
Description: Parse a boolean value from the buffer
Note | None documented |
---|
function ASN1GetBoolean(Buffer:PByte; Len:Integer; var Value:Boolean; var Next:PByte):Boolean;
Description: Read the next ASN1 tag from buffer and decode it as a boolean value
Note | None documented |
---|
ASN1 helper functions
function ASN1OIDEqual(const OID1,OID2:TASN1OID):Boolean;
Description: To be documented
Note | None documented |
---|
function ASN1OIDEqualPrefix(const OIDPrefix,OID:TASN1OID):Boolean;
Description: To be documented
Note | None documented |
---|
function ASN1OIDToString(const OID:TASN1OID):String;
Description: To be documented
Note | None documented |
---|
function ASN1BitStringToLongWord(Buffer:PByte; Len:Integer):LongWord;
Description: To be documented
Note | None documented |
---|
Return to Unit Reference