Can there be multiples of the same CHOICE field in a rfc5280 certificate? - certificate

I'm currently validating my implementation of a certificate conforming to the RFC5280.
The General Name is defined as:
GeneralName ::= CHOICE {
otherName [0] OtherName,
rfc822Name [1] IA5String,
dNSName [2] IA5String,
x400Address [3] ORAddress,
directoryName [4] Name,
ediPartyName [5] EDIPartyName,
uniformResourceIdentifier [6] IA5String,
iPAddress [7] OCTET STRING,
registeredID [8] OBJECT IDENTIFIER }
Now I can't find the definition of the CHOICE keyword. Is it possible for my certificate to contain multiple directoryName-, or URI-fields? Or does choice mean any of the below but not more than once?

Is it possible for my certificate to contain multiple directoryName-, or URI-fields?
Yes.
Or does choice mean any of the below but not more than once?
Also yes.
A choice is a single choice. It probably says it succinctly in the document somewhere, but ITU-T X.680 always refers to choices as single values, such as:
29.8 The choice type contains values which do not all have the same tag. (The tag depends on the alternative which contributed the value to the choice type.)
(emphasis mine)
The certificate can contain multiple directoryName/etc values because things like the subject alternative name extension don't have GeneralName values, they have GeneralNames values. And, of course, GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName

Related

X509 Decoder tool based on Certificate schema file

I am looking for a tool which is capable to decode X509 Certificated where additional Extensions are also added according to a predefined schema.
Similar to this. I assume if it is the typical notation for the schema, then someone must have implemented a generic parser for that.
FooProtocol DEFINITIONS ::= BEGIN
FooQuestion ::= SEQUENCE {
trackingNumber INTEGER(0..199),
question IA5String
}
FooAnswer ::= SEQUENCE {
questionNumber INTEGER(10..20),
answer BOOLEAN
}
FooHistory ::= SEQUENCE {
questions SEQUENCE(SIZE(0..10)) OF FooQuestion,
answers SEQUENCE(SIZE(1..10)) OF FooAnswer,
anArray SEQUENCE(SIZE(100)) OF INTEGER(0..1000),
...
}
END
or real life example for a given Object ID extension
boot_seq := SEQUENCE
{
certType INTEGER, -- indicates certificate type
bootCore INTEGER, -- indicates the core in the device that needs to be booted
bootCoreOpts INTEGER, -- Configuration options for the core being booted
destAddr OCTET STRING, -- Load address
imageSize INTEGER -- image size
}
Those are the tools that are capable of compiling ASN.1 schemas into data bindings in a variety of languages and platforms: https://www.itu.int/en/ITU-T/asn1/Pages/Tools.aspx
Heimdal in its master branch has an open source ASN.1 compiler that understands a subset of X.681/X.682/X.683 extensions and can actually fully decode a Certificate, including every kind of Attribute, Extension, and OtherName declared in lib/asn1/rfc2459.asn1 (and you can add more, rebuild, and use it).
It also can transliterate DER to JSON (but it's not X.697 JER compliant), so you can run asn1_print /path/to/DER/file Certificate and you'll get a beautiful JSON representation of the complete certificate, including all the attributes, extensions, and otherName SAN types that are declared in lib/asn1/rfc2459.asn1.

"In Unicode programs, must have the same structure layout, irrespective of the length" error

I'm now getting this error after making a small mod to a working program. The structures have the same type (though the tables are different) but I get this error? I've looked at similar postings but couldn't find an answer to this.
Codes snippets included.
* ---
,begin of TY_RESB_CDC
,MANDT type MANDT
,RSNUM type RSNUM
,RSPOS type RSPOS
,RSART type RSART
,UDATE type CDDATUM
,UTIME type CDUZEIT
.include type ZBW_MATERIAL_RESVN_RESB.
types: end of TY_RESB_CDC
,TT_RESB_CDC type hashed table of TY_RESB_CDC
with unique key RSNUM RSPOS RSART
,TT_RESB_STD type standard table of TY_RESB_CDC
with empty key
---
,LT_RESB_CDC type TT_RESB_CDC
,WA_RESB_CDC type TY_RESB_CDC "like LINE OF LT_RESB_CDC
,LT_RESB_STD type TT_RESB_STD
,WA_RESB_STD type TY_RESB_CDC "like line of LT_RESB_STD
---
move-corresponding <FS_DATA> to WA_RESB_STD.
" already exists in CDC
if WA_RESB_STD eq WA_RESB_CDC. "<FS_RESB_CDC>.
continue. "no change, skip this record
A component name cannot contain a dot in its name, in a Unicode program. Same for any other ABAP symbolic name.
The below code with name .include is not permitted. You were mistaken by DDIC structures, which have different rules.
TYPES: begin of TY_RESB_CDC,
...
UTIME type CDUZEIT,
.include type ZBW_MATERIAL_RESVN_RESB,
end of TY_RESB_CDC.
Instead, you should use the ABAP statement INCLUDE TYPE to include the components of a structure (e.g. ZBW_MATERIAL_RESVN_RESB in your case):
TYPES: begin of TY_RESB_CDC,
...
UTIME type CDUZEIT.
INCLUDE TYPE ZBW_MATERIAL_RESVN_RESB.
TYPES: end of TY_RESB_CDC.

How to escape special charcters?

I am using a html purifier package for purifying my rich text from any xss before storing in database.
But my rich text allows for Wiris symbols which uses special character as → or  .
Problem is the package does not allow me to escape these characters. It removes them completely.
What should I do to escape them ??
Example of the string before purifying
<p><math xmlns="http://www.w3.org/1998/Math/MathML"><msup><mi>x</mi><mn>2</mn></msup><mo> </mo><mo>+</mo><mo> </mo><mmultiscripts><mi>y</mi><mprescripts/><none/><mn>2</mn></mmultiscripts><mo> </mo><mover><mo>→</mo><mo>=</mo></mover><mo> </mo><msup><mi>z</mi><mn>2</mn></msup><mo> </mo></math></p>
After purifying
<p><math xmlns="http://www.w3.org/1998/Math/MathML"><msup><mi>x</mi><mn>2</mn></msup><mo> </mo><mo>+</mo><mo> </mo><mmultiscripts><mi>y</mi><mprescripts></mprescripts><none><mn>2</mn></mmultiscripts><mo> </mo><mover><mo>→</mo><mo>=</mo></mover><mo> </mo><msup><mi>z</mi><mn>2</mn></msup><mo> </mo></math></p>
My guess is that these entities are failing the regexen that HTML Purifier is using to check for valid entities in HTMLPurifier_EntityParser, here:
$this->_textEntitiesRegex =
'/&(?:'.
// hex
'[#]x([a-fA-F0-9]+);?|'.
// dec
'[#]0*(\d+);?|'.
// string (mandatory semicolon)
// NB: order matters: match semicolon preferentially
'([A-Za-z_:][A-Za-z0-9.\-_:]*);|'.
// string (optional semicolon)
"($semi_optional)".
')/';
$this->_attrEntitiesRegex =
'/&(?:'.
// hex
'[#]x([a-fA-F0-9]+);?|'.
// dec
'[#]0*(\d+);?|'.
// string (mandatory semicolon)
// NB: order matters: match semicolon preferentially
'([A-Za-z_:][A-Za-z0-9.\-_:]*);|'.
// string (optional semicolon)
// don't match if trailing is equals or alphanumeric (URL
// like)
"($semi_optional)(?![=;A-Za-z0-9])".
')/';
Notice how it expects numeric entities to start with 0 currently. (Perfectly sane since it's designed to handle pure HTML, without add-ons, and to make that safe; but in your use-case, you want more entity flexibility.)
You could extend that class and overwrite the constructor (where these regexen are being defined, by instead defining your own where you remove the 0* from the // dec part of the regexen), instantiating that, try setting $this->_entity_parser on a Lexer created with HTMLPurifier_Lexer::create($config) to your instantiated EntityParser object (this is the part I am least sure about whether it would work; you might have to create a Lexer patch with extends as well), then supply the altered Lexer to the config using Core.LexerImpl.
I have no working proof-of-concept of these steps for you right now (especially in the context of Laravel), but you should be able to go through those motions in the purifier.php file, before the return.
I solved the problem by setting key Core.EscapeNonASCIICharacters to true
under my default key in my purifier.php file and the problem has gone.

Encoding of a CHOICE type when the CHOICE itself is used with an implicit tag (using the specific example: CRLDistPoints)

The Botan crypto library has only a very limited support for the X.509 extension CRLDistributionPoint and actually throws an exception, if any of the "advanced" attributes of the extension are set which are not expected by Botan.
Hence, I try to patch the decoding of this extension, but I have a problem to correctly determine the type of the encoded objects based on the tags. Either this is an oversight in the specification for this extension (I doubt it) or I am subject to a fundamental misunderstanding of the encoding/decoding rules.
Here are the relevant parts of the specification
CertificateExtensions {joint-iso-itu-t ds(5) module(1)
certificateExtensions(26) 5} DEFINITIONS IMPLICIT TAGS
CRLDistPointsSyntax ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
DistributionPoint ::= SEQUENCE {
distributionPoint [0] DistributionPointName OPTIONAL,
reasons [1] ReasonFlags OPTIONAL,
cRLIssuer [2] GeneralNames OPTIONAL
}
DistributionPointName ::= CHOICE {
fullName [0] GeneralNames,
nameRelativeToCRLIssuer [1] RelativeDistinguishedName
}
The modules uses implicit tagging by default. In the following this will be important. A DistributionPoint is a SEQUENCE where all attributes are optional. The first optional attribute distributionPoint has the type tag 0 and is of type DistributionPointName. In turn, DistributionPointName is a CHOICE with possible choices which are either tag 0 (if GeneralNames is chosen) or tag 1 (if RelativeDistinguishedName is chosen).
According to my understanding, in case of implicit tagging a CHOICE type is encoded using the tag of the chosen type. In other words, a CHOICE type is not "nested" somehow but encoded on the same level on which the CHOICE type is used. But DistributionPointName has already been given the tag 0.
The specific question is: How is a DistributionPoint encoded, if nameRelativeToCRLIssuer (tag 1) is chosen as the choice for DistributionPointName without triggering a clash with tag 1 of the reasons attribute?
Here is an illustration of my problem:
30 // Type tag for outer SEQUENCE, DistributionPoint starts here
ll // Length of SEQUENCE, omitted here for editorial purposes
+--> 00 vs 01 // Type tag for distributionPoint
| // At first glance, 00 according to SEQUENCE definition for OPTIONAL DistributionPointName,
| // but maybe 01 if RelativeDistinguishedName is the selected CHOICE
| kk // Length of RelativeDistinguishedName, omitted here for editorial purposes
| vv // Encoding of RelativeDistinguishedName begins
| vv
| vv // Encoding of RelativeDistinguishedName ends, accordingly to length kk
+--> 01 // Type tag for OPTIONAL ReasonsFlags
jj // Length of ReasonsFlags
ww // Encoding of ReasonsFlags begins
ww
ww // Encoding of ReasonsFlags ends, accordingly to length jj
// Encoding of DistributionPoint ends, too, accordingly to length ll
In line three, the type tag should be 00 to indicate that the OPTIONAL DistributionPointName exists. This also avoids a clash with the type tag 01 in line 8 for the OPTIONAL ReasonFlags.
However, in line three, the type tag should also indicate which type has been chosen for DistributionPointName. :-(
According to my understanding, in case of implicit tagging a CHOICE
type is encoded using the tag of the chosen type. In other words, a
CHOICE type is not "nested" somehow but encoded on the same level on
which the CHOICE type is used. But DistributionPointName has already
been given the tag 0.
I'm afraid this is the opposite: CHOICE tagging is always explicit whatever the default tagging ...
In the X.680 document, there is following note
The tagging construction specifies explicit tagging if any of the following holds:
c) the "Tag Type" alternative is used and the value of "TagDefault" for
the module is IMPLICIT TAGS or AUTOMATIC TAGS, but the type defined by
"Type" is an untagged choice type, an untagged open type, or an
untagged "DummyReference" (see Rec. ITU-T X.683 | ISO/IEC 8824-4,
8.3).
So, if RelativeDistinguishedName is chosen, distributionPoint component tagging will be 0 (distributionPoint) and then 1 (RelativeDistinguishedName)
The reason for this is that CHOICE does not have a UNIVERSAL tag

X.509 Standard set of attributes order

I'm working with some legacy code, that implements a very basic X.509 parser. The code is quite old and I cannot distribute it.
This code reads the standard set of attributes in issuer and subject sequentially and in a specific order. As a basic example:
C=XX, O=MyOrganization, OU=MyOrganizationalUnit,
CN=myCommonName
So it would read the country, then the organization, and then the organizational unit and finally the common name.
I've been reading the standard (https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.4), (see section 4.1.2.4 and 4.1.2.6) and this legacy code somehow works with most certificates.
The question is if this set of attributes must follow a specific order and where it says so or the opposite.
The reason for that specific order is that Distinguished Names (DNs) were defined in the X.500 series of standards. X.500 is about directory services. X.500 directory servers have been mostly replaced by LDAP servers, but X.509, the part of the series that defines certificates, has survived for other purposes.
In a directory tree the most general node is at the top (in your example country) and then narrows down on every level of the tree. A person is usually a leaf in this tree:
C=US
|
O=Example1 ----- O=Example2
| |
OU=OU1-----OU=OU2 ...
| |
CN=XYZ ...
AFAIK X.500 includes some rules that define which attribute type can follow a certain attribute type in the tree, but unfortunately the documents are not freely available.
The order of the relative distinguished names (RDNs) in the subject or issuer DN of a certificate on an ASN.1 level reflects the order in the tree (i.e. top-down):
SEQUENCE {
SET {
SEQUENCE {
OBJECT IDENTIFIER=CountryName (2.5.4.6)
PRINTABLE STRING='US'
}
}
SET {
SEQUENCE {
OBJECT IDENTIFIER=OrganizationName (2.5.4.10)
PRINTABLE STRING='GeoTrust Inc.'
}
}
SET {
SEQUENCE {
OBJECT IDENTIFIER=CommonName (2.5.4.3)
PRINTABLE STRING='GeoTrust Global CA'
}
}
}
However, for the string representation of a DN there are two standards: OpenSSL shows the attributes by default as they are actually stored in the certificate, while RFC 2253/4514 reverses the order:
... the output consists of the string encodings of each
RelativeDistinguishedName in the RDNSequence (according to Section
2.2), starting with the last element of the sequence and moving
backwards toward the first.
CN=GeoTrust Global CA,O=GeoTrust Inc.,C=US
Also note that there are certificates "in the wild" which have multiple OUs in their DNs or less common attribute types from RFC 4519 like SERIALNUMBER or UID. I have also seen quite a few certificates, where the RDNs were actually encoded in the wrong order.