]> pd.if.org Git - zpackage/blob - libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / pk / asn1 / der / object_identifier / der_length_object_identifier.c
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
9 #include "tomcrypt.h"
10
11 /**
12   @file der_length_object_identifier.c
13   ASN.1 DER, get length of Object Identifier, Tom St Denis
14 */
15
16 #ifdef LTC_DER
17
18 unsigned long der_object_identifier_bits(unsigned long x)
19 {
20    unsigned long c;
21    x &= 0xFFFFFFFF;
22    c  = 0;
23    while (x) {
24      ++c;
25      x >>= 1;
26    }
27    return c;
28 }
29
30
31 /**
32   Gets length of DER encoding of Object Identifier
33   @param nwords   The number of OID words
34   @param words    The actual OID words to get the size of
35   @param outlen   [out] The length of the DER encoding for the given string
36   @return CRYPT_OK if successful
37 */
38 int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen)
39 {
40    unsigned long y, z, t, wordbuf;
41
42    LTC_ARGCHK(words  != NULL);
43    LTC_ARGCHK(outlen != NULL);
44
45
46    /* must be >= 2 words */
47    if (nwords < 2) {
48       return CRYPT_INVALID_ARG;
49    }
50
51    /* word1 = 0,1,2,3 and word2 0..39 */
52    if (words[0] > 3 || (words[0] < 2 && words[1] > 39)) {
53       return CRYPT_INVALID_ARG;
54    }
55
56    /* leading word is the first two */
57    z = 0;
58    wordbuf = words[0] * 40 + words[1];
59    for (y = 1; y < nwords; y++) {
60        t = der_object_identifier_bits(wordbuf);
61        z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0);
62        if (y < nwords - 1) {
63           /* grab next word */
64           wordbuf = words[y+1];
65        }
66    }
67
68    /* now depending on the length our length encoding changes */
69    if (z < 128) {
70       z += 2;
71    } else if (z < 256) {
72       z += 3;
73    } else if (z < 65536UL) {
74       z += 4;
75    } else {
76       return CRYPT_INVALID_ARG;
77    }
78
79    *outlen = z;
80    return CRYPT_OK;
81 }
82
83 #endif
84
85 /* ref:         $Format:%D$ */
86 /* git commit:  $Format:%H$ */
87 /* commit time: $Format:%ai$ */