home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / crypl200.zip / CRYPTLIB.ASN < prev    next >
Text File  |  1996-10-11  |  35KB  |  823 lines

  1. -/ This specification makes three slight deviations from the standard ASN.1
  2.    syntax to overcome some minor shortcoming in ASN.1.  The most obvious one
  3.    is the use of -//- comment delimiters (which work like C's /**/) in place
  4.    of standard ASN.1 delimiters, which require a seperate -- at the start of
  5.    each and every line of comment.
  6.  
  7.    Secondly, the specification defines a TAGDEF pseudo-type to make
  8.    management of explicit tags easier.  Instead of having to keep track of
  9.    [APPLICATION 2]'s scattered throughout one or more documents or relying on
  10.    an ASN.1 compiler to juggle automatic tags around, this pseudo-type allows
  11.    named tags so that the previous declaration would become [APPLICATION
  12.    TagName].  The tag values are then declared at the start of the
  13.    specification.  The use of application-specific tags is deprecated by some
  14.    authors because of the difficulty in managing the resulting confusion of
  15.    tag values; the TAGDEF pseudo-type attempts to alleviate this problem.
  16.  
  17.    Finally, ASN.1 has somewhat poor control over variant record structures
  18.    of the form:
  19.  
  20.     type of following record
  21.     record as defined by type taken from a predefined set of possibilities
  22.  
  23.    There are two ways in which ASN.1 allows this form of record to be
  24.    specified, the first being to use a CHOICE type:
  25.  
  26.     FooRecord ::= CHOICE {
  27.         type1   [0] Type1,
  28.         type2   [1] Type2,
  29.         ...
  30.         }
  31.  
  32.    However the choice is usually taken from a number of record types which
  33.    have already been allocated either unique ID's or object identifiers.
  34.    The use of implicit tagging then creates a second set of ID's (the tags)
  35.    alongside the existing ID's, leading to the same sort of confusion
  36.    created by the use of application-specific tags.   An alternative to the
  37.    use of CHOICE is to use ANY DEFINED BY:
  38.  
  39.     FooRecord ::= SEQUENCE {
  40.         typeID  INTEGER,
  41.         ANY DEFINED BY typeID
  42.         }
  43.  
  44.    This is similarly problematic since the functionality that is really
  45.    required of the ANY DEFINED BY is:
  46.  
  47.     ANY <of the following types> DEFINED BY typeID
  48.  
  49.    To solve this problem, the following definition extends the ASN.1 CHOICE
  50.    notation by replacing ANY DEFINED BY with a CHOICE type, but without the
  51.    usual tagging to differentiate the choices.  In order to distinguish this
  52.    type of nonstandard use, the text uses TYPED CHOICE instead of CHOICE in
  53.    the definition.  This does not affect the encoded form, but makes it
  54.    clearer from looking at the definitions what kind of records we can
  55.    expect in the ANY DEFINED BY position.
  56.  
  57.    The usual way around this problem is to use the ASN.1 macro extensions,
  58.    however requiring people to understand the contents of Annex A of ISO
  59.    8824:1988 (which has been described as "impenetrable"), with paragraphs
  60.    like:
  61.  
  62.     "The resulting type and value of an instance of use of the new value
  63.      notation is determined by the value (and the type of the value) finally
  64.      assigned to the distinguished local reference identified by the keyword
  65.      VALUE, according to the processing of the macrodefinition for the new
  66.      type notation followed by that for the new value notation"
  67.  
  68.    probably contravenes some sections of the Geneva Convention.  The 1993
  69.    extensions may also be employed to partially circumvent these problems,
  70.    but would probably make the result incomprehensible to someone unfamiliar
  71.    with ASN.1.  This specification uses the ASN.1 constraint notation, but
  72.    nothing more.
  73.  
  74.    To convert this specification into a form parseable by a standard ASN.1
  75.    compiler:
  76.  
  77.     - Insert a -- at the start of every comment line throughout the
  78.       document.
  79.     - Replace all occurrences of tag pseudo-types with their corresponding
  80.       values (this will make the resulting document difficult to maintain,
  81.       since hard-coded numbers will be scattered throughout the document).
  82.     - Replace all occurrences of TYPED CHOICE with EXTERNAL (this will make
  83.       type checking of the ANY DEFINED BY field impossible)
  84.  
  85.    The reason why the use of this specification with an unmodified ASN.1
  86.    compiler isn't considered a major issue is that all the ASN.1 routines
  87.    should probably be carefully hand-coded to allow for proper error recovery
  88.    from a denial-of-service attack in which an attacker transmits ASN.1
  89.    structures chosen to crash or otherwise negatively affect the code which
  90.    parses them.  After trying (and breaking) three ASN.1 compilers in this
  91.    way, the code used in cryptlib was hand-coded to perform very paranoid
  92.    checking of all input data.  This isn't a fault of the ASN.1 compilers,
  93.    which merely check for normal data errors.  What they don't handle so well
  94.    are errors specifically chosen by an attacker, after careful analysis of
  95.    the compiler, to crash the generated ASN.1 parsing code /-
  96.  
  97. cryptlib DEFINITIONS ::=
  98. BEGIN
  99.  
  100. -/ We export a few objects for external use.  Most of the low-level ones are
  101.    hidden within the library /-
  102.  
  103. EXPORTS
  104.     EncryptedKey, PKCEncryptedKey, Signature, EncryptedData, CompressedData,
  105.     SignedData;
  106.  
  107. -/ ID's for the algorithm types are defined externally (this is a logical
  108.    rather than a physical import since the syntax is incompatible as they're
  109.    declared in a C header file) /-
  110.  
  111. IMPORTS
  112.     CryptType, CryptMode FROM capi.h,
  113.     CRYPT_MAX_KEYSIZE, CRYPT_MAX_IVSIZE, CRYPT_MAX_HASHSIZE FROM capi.h;
  114.  
  115. -/ The application-specific tags /-
  116.  
  117. TAGDEF
  118.     TagEncryptedKey(0), TagPKCEncryptedKey(1), TagSignature(2),
  119.     TagEncryptedData(3), TagCompressedData(4), TagSignedData(5),
  120.     TagRawData(6), TagNonData(7), TagContinuation(8),
  121.     TagPublicKey(15), TagPrivateKey(16)
  122.  
  123. -/ In its simplest form an encrypted message will be:
  124.  
  125.     EncryptedKey( KeyInformation )
  126.     EncryptedData( Data )
  127.  
  128.    or
  129.  
  130.     PKCEncryptedKey( KeyInformation )
  131.     EncryptedData( Data )
  132.  
  133.    A signed message will be:
  134.  
  135.     SignedData( Data )
  136.     Signature
  137.  
  138.    (the Signature can be before or after the SignedData).
  139.  
  140.    A more complex message consisting of signed, PKC-encrypted data would be:
  141.  
  142.     PKCEncrypteKey( KeyInformation )
  143.     EncryptedData( SignedData( Data ), Signature )
  144.  
  145.    Note that the inner Data field in each of these cases can itself contain
  146.    further nestings of data fields /-
  147.  
  148. ------------------------------------------------------------------------------
  149. --                                                                            --
  150. --                    Data Format Definitions and Structures                    --
  151. --                                                                            --
  152. ------------------------------------------------------------------------------
  153.  
  154. -/ Compressed plaintext data (the format for this is currently undefined.
  155.    This data type should be regarded as being reserved for future use) /-
  156.  
  157. COMPRESSED { Data } ::= OCTET STRING ( CONSTRAINED BY
  158.     { -- Must be the result of the compression of -- Data }
  159.     )
  160.  
  161. CompressedData ::= [APPLICATION TagCompressedData] SEQUENCE {
  162.     ...                                -- Compression info, to be defined
  163.     dataContinued    BOOLEAN DEFAULT (FALSE)
  164.                                     -- Whether the data is further continued
  165.     data            COMPRESSED{Data}-- Compressed data
  166.     }
  167.  
  168. -/ Signed data.  The SignatureCookie ties the signed data to the signature
  169.    or signatures associated with it.  The signature is stored independantly
  170.    from the data in a Signature record (typically this follows the SignedData
  171.    record).  The set of MessageDigestParam's contains information on which
  172.    types of message digest to compute for the data in order to allow the
  173.    signature check to be done once the end of the data has been reached.
  174.    This is stored before the data itself to allow for one-pass processing /-
  175.  
  176. SignedData ::= [APPLICATION TagSignedData] SEQUENCE {
  177.     dataContinued    BOOLEAN DEFAULT (FALSE)
  178.                                     -- Whether the data is further continued
  179.     signatureCookie
  180.               [ 0 ]    IMPLICIT SignatureCookie,
  181.                                     -- Signature cookie
  182.     signatureDigestInfo    SET OF MessageDigestParams
  183.                                     -- Information on hashing for sig.check
  184.     data            Data            -- The data to be signed
  185.     }
  186.  
  187. -/ Encrypted data.  The IV is always present as a fixed-length string to
  188.    obscure the details of the algorithm and mode being used.  If necessary it
  189.    is extended to more than CRYPT_MAX_IVSIZE bytes by padding to the right
  190.    with 0 bits /-
  191.  
  192. EncryptedData ::= [APPLICATION TagEncryptedData] SEQUENCE {
  193.     dataContinued    BOOLEAN DEFAULT (FALSE)
  194.                                     -- Whether the data is further continued
  195.     keyCookie [ 0 ]    IMPLICIT KeyCookie,
  196.                                     -- Key cookie
  197.     iv                OCTET STRING (SIZE(CRYPT_MAX_IVSIZE)),    -- IV
  198.     data            ENCRYPTED{Data}    -- Encrypted data
  199.     }
  200.  
  201. -/ Raw data. This is the lowest level of nesting, data encapsulated at this
  202.    level is the raw data with no further nesting being possible /-
  203.  
  204. RawData ::= [APPLICATION TagRawData] SEQUENCE {
  205.     dataContinued    BOOLEAN DEFAULT (FALSE)
  206.                                     -- Whether the data is further continued
  207.     data            OCTET STRING    -- Raw data
  208.     }
  209.  
  210. -/ Non-data, used for message padding /-
  211.  
  212. NonData ::= [APPLICATION TagNonData] SEQUENCE {
  213.     dataContinued    BOOLEAN DEFAULT (FALSE)
  214.                                     -- Whether the data is further continued
  215.     data            OCTET STRING    -- Random padding
  216.     }
  217.  
  218. -/ Generic data.  Of the following options, the data fields of SignedData and
  219.    EncryptedData may contain nested data types; the data fields of NonData
  220.    and RawData cannot contain nested types /-
  221.  
  222. Data ::= CHOICE {
  223.     compressedData    CompressedData,
  224.     signedData        SignedData,
  225.     encryptedData    EncryptedData,
  226.     nonData            NonData,
  227.     rawData            RawData
  228.     }
  229.  
  230. -/ A continuation of a previous Data field.  This is provided in order to
  231.    work around the ASN.1 limitation that requires that the length of every
  232.    object (with potentially infinite levels of nesting) be known before a
  233.    single byte of data is output, since the TLV encoding requires storing the
  234.    length of the outer object at the start.  The Continuation record provides
  235.    a way to break a single larger record into a number of smaller sub-records
  236.    which are more amenable to processing by an application.  A continuation
  237.    record continues the type of the previous record.  For example to encrypt
  238.    a 45K when 16K I/O buffers are available, the encoded output would be:
  239.  
  240.     TagEncryptedData, 16384, TRUE, ...;
  241.     TagContinuation, 16384, TRUE, ...;
  242.     TagContinuation, 13312, ...;
  243.  
  244.    This allows large objects to be broken down into a palatable size.  The
  245.    Zip compressed data format uses a similar technique to break a data stream
  246.    into smaller chunks (typically with a 64K maximum size) for processing.
  247.    SDSI also uses this form of continuation.
  248.  
  249.    NOTE: This format isn't finalised yet, because it leads to problems with
  250.          multiple layers of encapsulation when the outer layer consists of
  251.          continuation records but the inner one doesn't, making it impossible
  252.          to strip off a layer at a time which may be necessary, for example,
  253.          if multiple signers exist and each one must be checked seperately /-
  254.  
  255. CONTINUATION { Data } ::= OCTET STRING ( CONSTRAINED BY
  256.     { -- Has the same implicit type as the immediately preceding piece --
  257.       -- of -- Data }
  258.     )
  259.  
  260. Continuation ::= [APPLICATION TagContinuation] SEQUENCE {
  261.     dataContinued    BOOLEAN DEFAULT (FALSE)
  262.                                     -- Whether the data is further continued
  263.     data            CONTINUATION{ Data }
  264.     }
  265.  
  266. ------------------------------------------------------------------------------
  267. --                                                                            --
  268. --                    Message Digest Definitions and Structures                --
  269. --                                                                            --
  270. ------------------------------------------------------------------------------
  271.  
  272. -/ The message digest object.  MessageDigest objects are used for various
  273.    purposes such as digital signatures and to identify other objects like
  274.    public keys /-
  275.  
  276. MessageDigest ::= SEQUENCE {
  277.     algorithm        CryptAlgorithm,    -- Message digest algorithm
  278.     algorithmInfo
  279.               [ 0 ]    IMPLICIT DigestAlgorithmInfo OPTIONAL,
  280.     digest            OCTET STRING (SIZE(1..CRYPT_MAX_HASHSIZE))
  281.                                     -- Message digest data
  282.     }
  283.  
  284. DigestAlgorithmInfo ::= TYPED CHOICE {
  285.     shaInfo            ShaInfo,        -- SHA parameters
  286.     ...
  287.     }
  288.  
  289. ShaInfo ::= SEQUENCE {
  290.     isSHA            BOOLEAN DEFAULT (FALSE)
  291.                                     -- Whether to use SHA rather than SHA1
  292.     }
  293.  
  294. -/ MessageDigest's are also used as key ID's.  Here they correspond to a MD
  295.    of the DER-encoded public portion of the key.  This is stored as part of
  296.    the key record to speed up lookups, and is better than the X.509 use of
  297.    serial numbers which assume some sort of centralized coordination system
  298.    for the management of serial numbers, or PGP's use of easily-spoofed key
  299.    LSB's.  In contrast hash-based ID's are (virtually) guaranteed to be
  300.    unique, and are much easier to manage /-
  301.  
  302. KeyID ::= MessageDigest
  303.  
  304. -/ The DER-encoded form of the MessageDigestInfo record is used as the data
  305.    value D when signing data as per PKCS #1.  The nonce is included to ensure
  306.    that no two people ever sign the same data.  This is used in preference
  307.    to PKCS #1's DigestInfo structure which requires AlgorithmIdentifiers
  308.    (which won't be defined yet for many newer algorithms, although they do
  309.    exist for all the broken and insecure digest algorithms), and which
  310.    doesn't include the nonce /-
  311.  
  312. MessageDigestInfo ::= SEQUENCE {
  313.     nonce            OCTET STRING (SIZE(8)),    -- Nonce
  314.     messageDigest    MessageDigest
  315.     }
  316.  
  317. -/ In order to make one-pass processing of signed data possible, we encode
  318.    the message digest parameters needed to process the data at the start of
  319.    the data.  This record is just a MessageDigest without the digest field /-
  320.  
  321. MessageDigestParams ::= SEQUENCE {
  322.     algorithm        CryptAlgorithm,    -- Message digest algorithm
  323.     algorithmInfo
  324.               [ 0 ]    IMPLICIT DigestAlgorithmInfo OPTIONAL
  325.     }
  326.  
  327. ------------------------------------------------------------------------------
  328. --                                                                            --
  329. --                    Key Encryption Definitions and Structures                --
  330. --                                                                            --
  331. ------------------------------------------------------------------------------
  332.  
  333. -/ The key control vector.  This contains a restriction bitmap in which each
  334.    bit, when turned on, locks out some operation for a key.  By default the
  335.    control vector consists of all zero bits, so that all operations for a key
  336.    are enabled.  The control vector is applied in the standard IBM-designed
  337.    way, except that SHA1 is used for the hashing instead of DES, and only a
  338.    maximum of 160 SHA1 output bits are xor'd into the key (this isn't a
  339.    problem in the original scheme when only DES was used, but becomes an
  340.    issue when different algorithms are involved).  If the control vector is
  341.    all zeroes, it is not applied to the encryption key.  The control vector
  342.    may also be used by hardware-based cryptlib interfaces which provide
  343.    access controls for keys stored by the hardware /-
  344.  
  345. ControlVector ::= BIT STRING {
  346.     CRYPT_CONTROL_LOCKED(0),        -- Control vector cannot be changed
  347.     CRYPT_CONTROL_NOENCRYPT(1),        -- Key cannot be used for encryption
  348.     CRYPT_CONTROL_NODECRYPT(2),        -- Key cannot be used for decryption
  349.     CRYPT_CONTROL_NOEXPORT(3),        -- Key cannot be exported
  350.     }
  351.  
  352. -/ Various parameterized types which codify the mapping from plaintext to
  353.    the encrypted form of the plaintext.  These are almost the same as the
  354.    ISO 9594-8 types of the same name, except that we use an OCTET STRING
  355.    rather than a BIT STRING, and differentiate between conventionally
  356.    encrypted data and public-key encrypted data, which is really an INTEGER
  357.    and not a bit/octet string /-
  358.  
  359. ENCRYPTED { Data } ::= OCTET STRING ( CONSTRAINED BY
  360.     { -- Must be the result of the encryption of -- Data }
  361.     )
  362.  
  363. PKCENCRYPTED { Data } ::= INTEGER ( CONSTRAINED BY
  364.     { -- Must be the result of the public-key encryption of -- Data }
  365.     )
  366.  
  367. -/ Algorithm parameters.  These are either present (and protected by
  368.    conventional or PKC encryption) along with the key in the KeyInformation
  369.    record, or externally visible in the PKCEncryptedKey record /-
  370.  
  371. CryptAlgorithmInfo ::= TYPED CHOICE {
  372.     desInfo            DesInfo,        -- DES parameters
  373.     des3Info        Des3Info,        -- Triple DES parameters
  374.     mdcshsInfo        MdcshsInfo,        -- MDC/SHS parameters
  375.     rc5Info            Rc5Info,        -- RC5 parameters
  376.     saferInfo        SaferInfo,        -- SAFER parameters
  377.     blowfishInfo    BlowfishInfo    -- Blowfish parameters
  378.     ...
  379.     }
  380.  
  381. DesInfo ::= SEQUENCE {                -- Default { FALSE }
  382.     isDESX            BOOLEAN            -- Whether to use DESX
  383.     }
  384.  
  385. Des3Info ::= SEQUENCE {                -- Default { FALSE }
  386.     isThreeKey        BOOLEAN            -- Whether to use 3-key triple DES
  387.     }
  388.  
  389. MdcShsInfo ::= SEQUENCE {            -- Default { FALSE, 200 }
  390.     useSHA1            BOOLEAN            -- Whether to use newer variant of SHA
  391.     keySetupIterations
  392.                     INTEGER            -- Number of key setup iterations
  393.     }
  394.  
  395. Rc5Info ::= SEQUENCE {                -- Default { 12 }
  396.     rounds            INTEGER            -- Number of encryption rounds
  397.     }
  398.  
  399. SaferInfo ::= SEQUENCE {            -- Default { FALSE, 6, or 10 for K128 }
  400.     useSaferSK        BOOLEAN,        -- Whether to use strengthened-key version
  401.     rounds            INTEGER,        -- No.encryption rounds
  402.     }
  403.  
  404. BlowfishInfo ::= SEQUENCE {            -- Default { FALSE, 10 }
  405.     useBlowfishSK        BOOLEAN        -- Whether to use strengthened-key version
  406.     keySetupIterations    INTEGER        -- No.iterations for SK user key setup
  407.     }
  408.  
  409. -/ The key cookie, which is used both as a check to make sure the session key
  410.    was recovered properly, and to tie the key with the data it is used to
  411.    encrypt.  This is defined as the first 4 bytes of the SHA-1 hash of the
  412.    raw session key (after any other transformation such as the application of
  413.    the control vector).
  414.  
  415.    One possible weakness of the use of key cookies is that if the same key is
  416.    exported multiple times with different control vectors for use by the same
  417.    recipient, the key cookie can be used to select the less-constrained key.
  418.    The same effect could normally be obtained by changing the code to ignore
  419.    control vectors, but it may become a problem in environments where the
  420.    encryption is implemented as a secure module which actually enforces the
  421.    use of control vectors.  Although the scenario of multiple identical keys
  422.    with different control vectors being exported to the same recipient is
  423.    unlikely, the key cookie is made an optional parameter in order to
  424.    eliminate this possible problem /-
  425.  
  426. KeyCookie ::= OCTET STRING (SIZE(4))
  427.  
  428. -/ The key information object.  This is then encrypted using a conventional
  429.    or public-key algorithm to create an EncryptedKey or PKCEncryptedKey.
  430.  
  431.    When a KeyInformation object is encrypted with a conventional algorithm,
  432.    the padding field should be used to obscure the total size of the object,
  433.    otherwise it will be possible to infer information on the algorithm type
  434.    from the size of the KeyInformation object.  As a general guide, adding
  435.    padding to take the KeyInformation object to the nearest multiple of 64
  436.    bytes is a good way to obstruct object-size-based traffic analysis /-
  437.  
  438. KeyInformation ::= SEQUENCE {
  439.     algorithm        CryptAlgorithm,    -- Encryption algorithm
  440.     mode            CryptMode,        -- Encryption mode
  441.     algorithmInfo
  442.               [ 0 ]    IMPLICIT CryptAlgorithmInfo OPTIONAL,
  443.                                     -- Extra information needed by the
  444.                                     -- encryption algorithm
  445.     key                OCTET STRING (SIZE(1..CRYPT_MAX_KEYSIZE)),
  446.                                     -- The key itself
  447.     padding            OCTET STRING OPTIONAL
  448.                                     -- Padding to hide the total data size
  449.     }
  450.  
  451. -/ The conventional-key encrypted key object.  This contains a KeyInformation
  452.    object encrypted with the conventional key, which may or may not have been
  453.    derived from a longer user key.  If the conventional key was derived from
  454.    a longer user key, the parameters (hash algorithm used and number of
  455.    iterations) are included in the record.
  456.  
  457.    Although the encrypted key could be an EncryptedData record, this just
  458.    adds another level of unnecessary complexity (and the encrypted key is
  459.    really an integeral part of the EncryptedKey record, not a seperate
  460.    EncryptedData record) so we treat the IV (if the encryption mode being
  461.    used requires one) and encrypted key as intrinsic fields of the
  462.    EncryptedData record /-
  463.  
  464. EncryptedKey ::= [APPLICATION TagEncryptedKey] SEQUENCE {
  465.     algorithm        CryptAlgorithm,    -- Encryption algorithm
  466.     mode            CryptMode,        -- Encryption mode
  467.     algorithmInfo
  468.               [ 0 ]    IMPLICIT CryptAlgorithmInfo OPTIONAL,
  469.                                     -- Extra information needed by the
  470.                                     -- encryption algorithm
  471.     keyDerivationInfo
  472.               [ 1 ]    IMPLICIT KeyDerivationInfo OPTIONAL,
  473.     keyCookie [ 2 ]    IMPLICIT KeyCookie,
  474.                                     -- Cookie for the encrypted key
  475.     controlVector
  476.               [ 3 ]    IMPLICIT ControlVector OPTIONAL,
  477.                                     -- Key control vector for encrypted key
  478.     iv          [ 4 ]    IMPLICIT OCTET STRING (SIZE(1...CRYPT_MAX_IVSIZE)),
  479.                                     -- IV
  480.     encryptedKey    ENCRYPTED{KeyInformation}
  481.                                     -- The encrypted keying information
  482.     }
  483.  
  484. -/ The parameters used to derive the conventional encryption key from the
  485.    user key.  Usually we use the key directly, but sometimes it may have
  486.    been derived from a longer user key by multiple applications of a hash
  487.    function, which is encoded in this record /-
  488.  
  489. KeyDerivationInfo ::= SEQUENCE {
  490.     algorithm        CryptAlgorithm,    -- Hash algorithm used to derive key
  491.     algorithmInfo
  492.               [ 0 ]    IMPLICIT DigestAlgorithmInfo OPTIONAL
  493.     iterations        INTEGER            -- Number of iterations of hash
  494.     }
  495.  
  496. -/ The PKC-encrypted key object.  X.509 uses a BIT STRING, this format is
  497.    more rigorous.  Normally all information needed to recreate the session
  498.    key (including the algorithm, mode, and various parameters) is contained
  499.    inside the KeyInformation object.  However Diffie-Hellman works somewhat
  500.    differently and doesn't allow the exchange of information, merely the
  501.    agreement on a shared secret.  For this reason the parameters for the
  502.    conventional encryption algorithm are explicitly specified in the
  503.    PKCAlgorithmInfo field rather than being part of the KeyInformation, and
  504.    the keyCookie field is meaningless and is omitted /-
  505.  
  506. PKCEncryptedKey ::= [APPLICATION TagPKCEncryptedKey] SEQUENCE {
  507.     keyID            KeyID,            -- Key ID of encrypting key
  508.     algorithm        CryptAlgorithm,    -- Key encryption algorithm type
  509.     algorithmInfo
  510.               [ 0 ]    IMPLICIT PKCAlgorithmInfo OPTIONAL,
  511.                                     -- Extra information needed by the
  512.                                     -- encryption algorithm.
  513.     keyCookie [ 1 ]    IMPLICIT KeyCookie,
  514.                                     -- Cookie for the encrypted key
  515.     controlVector
  516.               [ 2 ]    IMPLICIT ControlVector OPTIONAL,
  517.                                     -- Key control vector for encrypted key
  518.     encryptedKey    PKCEncryptedKeyInformation
  519.                                     -- The encrypted keying information
  520.     }
  521.  
  522. PKCAlgorithmInfo ::= TYPED CHOICE {
  523.     dhInfo                DhInfo,        -- Diffie-Hellman parameters
  524.     ...
  525.     }
  526.  
  527. DhInfo ::= SEQUENCE {
  528.     algorithm        CryptAlgorithm,    -- Conventional encryption algorithm
  529.     mode            CryptMode,        -- Conventional encryption mode
  530.     algorithmInfo
  531.               [ 0 ]    IMPLICIT CryptAlgorithmInfo OPTIONAL,
  532.                                     -- Extra information needed by the
  533.                                     -- conventional encryption algorithm.
  534.     }
  535.  
  536. -/ The encrypted key information itself, which for most algorithms is just an
  537.    integer containing a KeyInformation record encrypted with the appropriate
  538.    public-key algorithm.  For Diffie-Hellman the shared secret is taken from
  539.    the least-significant bits of the resulting integer value, for example an
  540.    IDEA key would be integer[ length-16 ... length ] if the integer is stored
  541.    in big-endian form /-
  542.  
  543. PKCEncryptedKeyInformation ::= TYPED CHOICE {
  544.     dhEncryptedKey    DHEncryptedKey    -- DH shared information
  545.     rsaEncryptedKey    RSAEncryptedKey    -- RSA encrypted data
  546.     ...
  547.     }
  548.  
  549. DHEncryptedKey ::= PKCENCRYPTED{KeyInformation}
  550.                                     -- DH shared information
  551. RSAEncryptedKey ::= PKCENCRYPTED{KeyInformation}
  552.                                     -- RSA encrypted data
  553.  
  554. ------------------------------------------------------------------------------
  555. --                                                                            --
  556. --                Digital Signature Definitions and Structures                --
  557. --                                                                            --
  558. ------------------------------------------------------------------------------
  559.  
  560. -/ The signature cookie, a 64-bit nonce which is used to tie a signature and
  561.    data block together /-
  562.  
  563. SignatureCookie ::= OCTET STRING (SIZE(8))
  564.  
  565. -/ A parameterized type which codifies the mapping from data to the signed
  566.    form of the data.  Some sort of SEQUENCE would make more sense here, but
  567.    X.509 uses a BIT STRING and then encapsulates a SEQUENCE inside it where
  568.    necessary (this is probably a design defect in X.509, because it wasn't
  569.    anticipated that a signature would contain more than one primitive
  570.    component).
  571.  
  572.    The signature itself is just (usually) a BIT STRING containing an integer
  573.    which is the result of wrapping up a MessageDigestInfo record as per
  574.    PKCS #1 and encrypted it with the appropriate public-key algorithm,
  575.    however in some cases it contains a BIT STRING which encapsulates a
  576.    SEQUENCE which contains the output of the signature algorithm (eg DSA,
  577.    ElGamal) /-
  578.  
  579. SIGNED { Data } ::= BIT STRING ( CONSTRAINED BY
  580.     { -- Must be the result of the private-key encryption of -- Data }
  581.     )
  582.  
  583. -/ The signature object /-
  584.  
  585. Signature ::= [APPLICATION TagSignature] SEQUENCE {
  586.     keyID            KeyID,            -- Key ID of signers key
  587.     algorithm        CryptAlgorithm,    -- Signature algorithm type
  588.     algorithmInfo
  589.               [ 0 ]    IMPLICIT SignatureAlgorithmInfo OPTIONAL,
  590.                                     -- Extra information needed by the
  591.                                     -- encryption algorithm.
  592.     signatureCookie
  593.               [ 1 ]    SignatureCookie    -- Signature cookie for this signature
  594.     signatureInfo    SIGNED {MessageDigestInfo}
  595.                                     -- The signature itself
  596.     }
  597.  
  598. SignatureAlgorithmInfo ::= TYPED CHOICE {
  599.     ...
  600.     }
  601.  
  602. ------------------------------------------------------------------------------
  603. --                                                                            --
  604. --                                Public/Private Keys                            --
  605. --                                                                            --
  606. ------------------------------------------------------------------------------
  607.  
  608. -/ The general public and private key objects.  Each key is identified by a
  609.    MessageDigest record containing the MD of the DER-encoded form of the key
  610.    components.  This is stored as part of the key record to speed up lookups,
  611.    and is better than the X.509 use of serial numbers which assume some sort
  612.    of centralized coordination system for the management of serial numbers,
  613.    or PGP's use of easily-spoofed key LSB's.  In contrast hash-based ID's are
  614.    (virtually) guaranteed to be unique, and are much easier to manage.
  615.  
  616.    The key record also contains a validity period for the key, which is
  617.    independant of the validity period of the keys certification (for example
  618.    a key certificate may have a validity period of only an hour, or even "for
  619.    the duration of a single transaction"), whereas the key validity times are
  620.    for the key itself, not its certification.
  621.  
  622.    The public key is simply the X.509 SubjectPublicKeyInfo record which
  623.    comprises the payload of an X.509 CertificateInfo certificate.  It is
  624.    assumed that this record will be stored in some form of database,
  625.    indexed by either user ID or key ID which are stored in separate records.
  626.  
  627.    [Perhaps this should be a full X.509 v3 Certificate with many fields set
  628.     to NULL if no certifying information is present]
  629.  
  630.    The private key isn't so simple, since there is no standard format for
  631.    this (or, rather, there are half a dozen non-standard formats for it), so
  632.    we define our own one (one more non-standard can't hurt).
  633.  
  634.    These formats are somewhat vague because there aren't any standards
  635.    available - X.509 public keys are assumed to be stored in an X.500
  636.    directory or online, and private keys are assumed to be stored somewhere
  637.    in hyperspace.  The eventual goal is probably to store full X.509 certs
  638.    for the public keys and [something] for the private keys /-
  639.  
  640. PublicKey ::= SubjectPublicKeyInfo    -- X.509 public key information record
  641.  
  642. PrivateKey ::= [APPLICATION TagPrivateKey] SEQUENCE {
  643.     keyID            KeyID,            -- Key ID of following record
  644.     validFrom [ 0 ] Time DEFAULT (0),    -- Valid from date
  645.     validTo      [ 1 ]    Time DEFAULT (0),    -- Valid to date
  646.     algorithm        PKCAlgorithm,    -- PKC algorithm type
  647.     privateKey        PrivateKeyInfo    -- Private key information
  648.     }
  649.  
  650. PrivateKeyInfo ::= TYPED CHOICE {
  651.     rsaPrivateKey    RSAPrivateKeyInfo,    -- RSA private key
  652.     dssPrivateKey    DSSPrivateKeyInfo    -- DSS private key
  653.     ...
  654.     }
  655.  
  656. -/ The public key information, an X.509 SubjectPublicKeyInfo record.  The
  657.    definition is given here for completeness, see X.509 and many related
  658.    standards, along with assorted drafts, alterations, and amendments, for
  659.    full details /-
  660.  
  661. SubjectPublicKeyInfo ::= SEQUENCE {
  662.     algorithm        AlgorithmIdentifier,-- Algorithm identifier for PKC
  663.     subjectPublicKey BITSTRING            -- Public key fields
  664.     }
  665.  
  666. AlgorithmIdentifier ::= SEQUENCE {
  667.     algorithm        ALGORITHM.&id( { SupportedAlgorithms } ),
  668.     parameters        ALGORITHM.&Type( { SupportedAlgorithms }{ @algorithm } )
  669.                         OPTIONAL
  670.     }
  671.  
  672. SupportedAlgorithms ALGORITHM ::= { ... }
  673.  
  674. ALGORITHM ::= TYPE-IDENTIFIER
  675.  
  676. RSAPublicKey ::= SEQUENCE {
  677.     modulus            INTEGER,        -- Modulus n
  678.     publicExponent    INTEGER            -- Public exponent e
  679.     }
  680.  
  681. DSAPublicKey ::= INTEGER
  682.  
  683. -/ The RSA private key.  There are two forms of this structure, the normal
  684.    one which is identical to the PKCS #1 definition, and an encrypted form
  685.    which protects the private fields.  PKCS #8 defines a method for
  686.    encrypting the private key, but this is rather limited and doesn't
  687.    generalize well.  In addition there is no need to encrypt the public
  688.    fields, which means that part of the private key can be used as a public
  689.    key if necessary.  In this respect the following format is closer to the
  690.    one used in PGP (which also only encrypts the private fields), except that
  691.    again it's more general than the PGP one.
  692.  
  693.    Of the private key fields, only the fields n and d are really needed.  e
  694.    is present to allow the public key to be constructed from it.  p, q,
  695.    d mod (p-1), d mod (p-1), and (q^-1) mod p are intended for efficiency and
  696.    may not be used by some implementations.  Although these fields aren't
  697.    absolutely necessary, reconstructing them is inefficient, and the library
  698.    will assume they are present, along with exponent1 and exponent2.  These
  699.    last two fields aren't present in PGP keys, and will be created by the
  700.    library when the keys are loaded if necessary /-
  701.  
  702. RSAPrivateKeyInfo ::= CHOICE {
  703.     rsaPrivateKey
  704.               [ 0 ]    RSAPrivateKey,    -- RSA private key
  705.     rsaEncryptedPrivateKey
  706.               [ 1 ]    RSAEncryptedPrivateKey
  707.                                     -- Encrypted RSA private key
  708.     }
  709.  
  710. RSAPrivateKey ::= SEQUENCE {
  711.     version            INTEGER(0),        -- Version number
  712.     modulus            INTEGER,        -- Modulus n
  713.     publicExponent    INTEGER,        -- Public exponent e
  714.     privateExponent    INTEGER,        -- Private exponent d
  715.     prime1            INTEGER,        -- Prime factor p of n
  716.     prime2            INTEGER,        -- Prime factor d of n
  717.     exponent1        INTEGER,        -- d mod (p-1)
  718.     exponent2        INTEGER,        -- d mod (q-1)
  719.     coefficient        INTEGER            -- CRT coefficient (q^-1) mod p
  720.     }
  721.  
  722. RSAEncryptedPrivateKey ::= SEQUENCE {
  723.     version            INTEGER,        -- Always 0, included for PKCS compat.
  724.     modulus            INTEGER,        -- Modulus n
  725.     publicExponent    INTEGER,        -- Public exponent e
  726.  
  727. -/ Make the next bit like an EncryptedKey but have RSAPrivateFields in place
  728.    of the KeyInformation record?  It needs the EncryptedKey fields, but
  729.    linking in the structure is a bit messy /-
  730.     encryptedRSAKey    ENCRYPTED{RSAPrivateFields}
  731.                                     -- Encrypted RSA private key fields
  732.     }
  733.  
  734. RSAPrivateFields ::= SEQUENCE {
  735.     {
  736.     privateExponent    INTEGER,        -- Private exponent d
  737.     prime1            INTEGER,        -- Prime factor p of n
  738.     prime2            INTEGER,        -- Prime factor d of n
  739.     exponent1        INTEGER,        -- d mod (p-1)
  740.     exponent2        INTEGER,        -- d mod (q-1)
  741.     coefficient        INTEGER            -- CRT coefficient (q^-1) mod p
  742.     }
  743.  
  744. -/ PKCS #8 has the following:
  745.  
  746. PrivateKeyInfo ::= SEQUENCE {
  747.     version            INTEGER(0),        -- Version number
  748.     privateKeyAlgorithm
  749.                     AlgorithmIdentifier,
  750.                                     -- Private-key algorithm
  751.     privateKey        OCTETS STRING,    -- Private key data
  752.     attributes[ 0 ]    IMPLICIT Attributes OPTIONAL
  753.                                     -- Extended attributes for key
  754.     }
  755.  
  756.    and then encrypts this.  However this area isn't standardised at all,
  757.    Netscape wraps this up in an EncryptedPrivateKeyInfo object which is in
  758.    turn wrapped up in Netscapes own encryption object.  This format has the
  759.    unfortunate property of providing around 100 bytes of known plaintext
  760.    for an attacker for a 1024-bit key /-
  761.  
  762. ------------------------------------------------------------------------------
  763. --                                                                            --
  764. --                    Key Collection Definitions and Structures                --
  765. --                                                                            --
  766. ------------------------------------------------------------------------------
  767.  
  768. -/ The following definitions are for records which will allow public-key data
  769.    to be moved portably from one system to another.  This work is currently
  770.    incomplete /-
  771.  
  772. -/ The header for key collections.  This contains useful information about
  773.    the key collection such as the number of keys in the collection (which can
  774.    be useful for giving feedback to the user during operations which process
  775.    the entire key collection), the maximum version number of any object in
  776.    the key collection, and a description of the key collection (which avoids
  777.    relying on changeable and often very limited filenames to identify key
  778.    collections) /-
  779.  
  780. KeyHeader ::= SEQUENCE {
  781.     noRecords        INTEGER            -- No.of key records in this collection
  782.     version            INTEGER            -- Max.vers.no.of any record in collection
  783.     description
  784.               [ 0 ] GeneralizedString OPTIONAL
  785.                                     -- Description of this key collection
  786.     ...
  787.     }
  788.  
  789. -/ The key record for public key collections.  This contains the public key,
  790.    any information associated with it, and any certificates for the key.  It
  791.    may also contain an optional restart marker which allows for error
  792.    recovery if part of a key collection becomes corrupted.  The a string
  793.    contains a sequence of values which have been chosen to be unlikely to
  794.    occur otherwise in a key record and which are sensitive to various types
  795.    of corruption.  The CR and LF will detect an FTP transfer in text mode.
  796.    The 0xA0 is an ASCII space character with the high bit set to detect a
  797.    transfer over a system which isn't 8-bit clean.  The 0x00 rarely occurs in
  798.    key records since it's not needed to terminate strings.  The entire
  799.    restart marker as encoded is the hex sequence 0x08, 0x04, 0x0D, 0x0A,
  800.    0xA0, 0x00 which is what the restart code checks for (conveniently, the
  801.    octet string header is encoded using backspace and EOT characters,
  802.    another potential target for/detector of mangling) /-
  803.  
  804. PublicKeyRecord ::= SEQUENCE {
  805.     restartMarker    OCTET STRING ('0D0AA000'H),
  806.     key                PublicKey,        -- The public key itself
  807.     keyInfo            SET OF KeyInfo,    -- Information associated with the key
  808.     keyCertificates    SET OF KeyCertificates    -- Key certificates
  809.     }
  810.  
  811. KeyInfo ::= CHOICE {
  812.     address      [ 0 ] IMPLICIT AddressInfo,    -- Physical address
  813.     email      [ 1 ] IMPLICIT EmailInfo,    -- Email address
  814.     phone      [ 2 ] IMPLICIT PhoneInfo,    -- Phone/fax/pager number
  815.     ...
  816.     }
  817.  
  818. KeyCertificate ::= CHOICE {
  819.     ...
  820.     }
  821.  
  822. END
  823.