8

From the X.509 specs:

   CRLReason ::= ENUMERATED {
        unspecified             (0),
        keyCompromise           (1),
        cACompromise            (2),
        affiliationChanged      (3),
        superseded              (4),
        cessationOfOperation    (5),
        certificateHold         (6),
             -- value 7 is not used
        removeFromCRL           (8),
        privilegeWithdrawn      (9),
        aACompromise           (10) }

...and...

Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }

Why isn't Version an ENUMERATED type? And similarly, why isn't CRLReason an INTEGER?

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
ansur
  • 183
  • 1
  • 3

2 Answers2

6

ENUMERATED and INTEGER serve different purposes. ENUMERATED is for creating a list of named items while INTEGER is for carrying numbers. The fact that the type notation seems somewhat similar does not make them identical. For ENUMERATED, the only values permitted are those named in the list. For INTEGER, the named list is just a set of useful labels for specific numbers, and does not limit what values are permitted for the INTEGER type.

I can only assume that CRLReason was made ENUMERATED because there is a closed set of values while Version was made an INTEGER to leave the number of future versions open ended.

Feel free to try some of these specifications at http://asn1-playground.oss.com, which is an online ASN.1 compiler and encoder/decoder that supports not only BER and DER, but also PER, XER and CER. You will be able to see that differences between ENUMERATED and INTEGER seem more significant for other encoding rules (such as PER and XER) than they seem for BER and DER.

Paul Thorpe
  • 196
  • 1
  • 4
5

ENUMERATED and INTEGER are almost identical (they just use distinct tags). The generic idea is that ENUMERATED is for a choice within a bounded set of possible values, whereas INTEGER is for values which could, at least theoretically, raise indefinitely.

Here, the use of ENUMERATED for CRLReasons is a hint which says that "there shall be no other reason in the future", whereas there may well be other protocol versions (possibly many others).

Now that's just a declaration of intent, which will not be enforced in any way. Remember that the justification of most of ASN.1 is: "it looked like a good idea at that time". Do not try to read too much in it. After all, ASN.1 succeeded in defining, well into the 1980s, a format for dates which has only two digits for the year -- a glaring Y2K issue, which did not deter the standardization committee... so just accept the ENUMERATED/INTEGER duality as one of the numerous quirks of ASN.1 (it's not the worse).

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • 1
    Paul's answer is more correct in that they serve different purposes. The fact that ASN.1 supports named integers in the first place is a quirk; it would have been better for all enumerated values (e.g. named constants as found in cpp `#define`) to be represented as ENUMERATED. X.509's use of INTEGER for Version is another quirk that would have been avoided had ASN.1 not enabled it. ENUMERATED can be extended in the future - the lack of a `...` is the hint that it won't be. See Larmouth, section 12.4: https://books.google.com/books?id=F-UJp_esh9QC&pg=PA208. – Dave Sep 08 '16 at 16:54