1 // SPDX-License-Identifier: BSD-2-Clause
2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3  *
4  * LibTomCrypt is a library that provides various cryptographic
5  * algorithms in a highly modular and flexible manner.
6  *
7  * The library is free for all purposes without any express
8  * guarantee it works.
9  */
10 #include "tomcrypt_private.h"
11 
12 /**
13   @file der_encode_utctime.c
14   ASN.1 DER, encode a  UTCTIME, Tom St Denis
15 */
16 
17 #ifdef LTC_DER
18 
19 static const char * const baseten = "0123456789";
20 
21 #define STORE_V(y) \
22     out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \
23     out[x++] = der_ia5_char_encode(baseten[y % 10]);
24 
25 /**
26   Encodes a UTC time structure in DER format
27   @param utctime      The UTC time structure to encode
28   @param out          The destination of the DER encoding of the UTC time structure
29   @param outlen       [in/out] The length of the DER encoding
30   @return CRYPT_OK if successful
31 */
der_encode_utctime(const ltc_utctime * utctime,unsigned char * out,unsigned long * outlen)32 int der_encode_utctime(const ltc_utctime   *utctime,
33                              unsigned char *out,   unsigned long *outlen)
34 {
35     unsigned long x, tmplen;
36     int           err;
37 
38     LTC_ARGCHK(utctime != NULL);
39     LTC_ARGCHK(out     != NULL);
40     LTC_ARGCHK(outlen  != NULL);
41 
42     if ((err = der_length_utctime(utctime, &tmplen)) != CRYPT_OK) {
43        return err;
44     }
45     if (tmplen > *outlen) {
46         *outlen = tmplen;
47         return CRYPT_BUFFER_OVERFLOW;
48     }
49 
50     /* store header */
51     out[0] = 0x17;
52 
53     /* store values */
54     x = 2;
55     STORE_V(utctime->YY);
56     STORE_V(utctime->MM);
57     STORE_V(utctime->DD);
58     STORE_V(utctime->hh);
59     STORE_V(utctime->mm);
60     STORE_V(utctime->ss);
61 
62     if (utctime->off_mm || utctime->off_hh) {
63        out[x++] = der_ia5_char_encode(utctime->off_dir ? '-' : '+');
64        STORE_V(utctime->off_hh);
65        STORE_V(utctime->off_mm);
66     } else {
67        out[x++] = der_ia5_char_encode('Z');
68     }
69 
70     /* store length */
71     out[1] = (unsigned char)(x - 2);
72 
73     /* all good let's return */
74     *outlen = x;
75     return CRYPT_OK;
76 }
77 
78 #endif
79 
80 /* ref:         $Format:%D$ */
81 /* git commit:  $Format:%H$ */
82 /* commit time: $Format:%ai$ */
83