1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** NetX Secure Component */
17 /** */
18 /** X.509 Digital Certificates */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define NX_SECURE_SOURCE_CODE
24
25 #include "nx_secure_x509.h"
26
27
28 /**************************************************************************/
29 /* */
30 /* FUNCTION RELEASE */
31 /* */
32 /* _nx_secure_x509_key_usage_extension_parse PORTABLE C */
33 /* 6.1.6 */
34 /* AUTHOR */
35 /* */
36 /* Timothy Stapko, Microsoft Corporation */
37 /* */
38 /* DESCRIPTION */
39 /* */
40 /* This function parses through an X.509 certificate keyUsage */
41 /* extension and returns the Authentication Key Usage bitfield for use */
42 /* by the application. */
43 /* */
44 /* INPUT */
45 /* */
46 /* certificate Pointer to X.509 certificate */
47 /* bitfield keyUsage bitfield return */
48 /* */
49 /* OUTPUT */
50 /* */
51 /* status Completion status */
52 /* */
53 /* CALLS */
54 /* */
55 /* _nx_secure_x509_asn1_tlv_block_parse Parse ASN.1 block */
56 /* _nx_secure_x509_extension_find Find extension in certificate */
57 /* */
58 /* CALLED BY */
59 /* */
60 /* Application Code */
61 /* */
62 /* RELEASE HISTORY */
63 /* */
64 /* DATE NAME DESCRIPTION */
65 /* */
66 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
67 /* 09-30-2020 Timothy Stapko Modified comment(s), */
68 /* fixed parsing issue, */
69 /* resulting in version 6.1 */
70 /* 04-02-2021 Timothy Stapko Modified comment(s), */
71 /* removed dependency on TLS, */
72 /* resulting in version 6.1.6 */
73 /* */
74 /**************************************************************************/
_nx_secure_x509_key_usage_extension_parse(NX_SECURE_X509_CERT * certificate,USHORT * bitfield)75 UINT _nx_secure_x509_key_usage_extension_parse(NX_SECURE_X509_CERT *certificate, USHORT *bitfield)
76 {
77 USHORT tlv_type;
78 USHORT tlv_type_class;
79 ULONG tlv_length;
80 const UCHAR *tlv_data;
81 const UCHAR *current_buffer;
82 ULONG length;
83 ULONG header_length;
84 UINT status;
85 NX_SECURE_X509_EXTENSION key_usage_extension;
86
87 /* Find and parse the keyUsage extension. */
88 /* keyUsage ASN.1 format:
89
90 id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
91
92 KeyUsage ::= BIT STRING {
93 digitalSignature (0),
94 nonRepudiation (1), -- recent editions of X.509 have
95 -- renamed this bit to contentCommitment
96 keyEncipherment (2),
97 dataEncipherment (3),
98 keyAgreement (4),
99 keyCertSign (5),
100 cRLSign (6),
101 encipherOnly (7),
102 decipherOnly (8) }
103 */
104
105 /* Find the KeyUsage extension in the certificate. */
106 status = _nx_secure_x509_extension_find(certificate, &key_usage_extension, NX_SECURE_TLS_X509_TYPE_KEY_USAGE);
107
108 /* See if extension present - it is OK if not present! */
109 if (status != NX_SECURE_X509_SUCCESS)
110 {
111 return(status);
112 }
113
114 /* The length of our extensions is the length of the sequence. */
115 current_buffer = key_usage_extension.nx_secure_x509_extension_data;
116 length = key_usage_extension.nx_secure_x509_extension_data_length;
117
118 /* Parse the bit string. */
119 status = _nx_secure_x509_asn1_tlv_block_parse(current_buffer, &length, &tlv_type, &tlv_type_class, &tlv_length, &tlv_data, &header_length);
120
121 /* Make sure we parsed the block alright. */
122 if (status != 0)
123 {
124 return(status);
125 }
126
127 /* If the next item up is not a sequence, then it isn't an extensions block. */
128 if (!(tlv_type_class == NX_SECURE_ASN_TAG_CLASS_UNIVERSAL && tlv_type == NX_SECURE_ASN_TAG_BIT_STRING))
129 {
130 /* We were expecting a bitfield but got something else. */
131 return(NX_SECURE_X509_INVALID_EXTENSION_SEQUENCE);
132 }
133
134 /* Check the bit string length. */
135 if (tlv_length > sizeof(USHORT) || tlv_length < 2)
136 {
137 return(NX_SECURE_X509_INVALID_EXTENSION_SEQUENCE);
138 }
139
140 /* DER-encoding of a BIT STRING with flag values uses the top octet of the 2 byte string
141 to encode the number of 0 bits at the end of the lower octet. Thus, we need to extract
142 the top byte and shift the bottom byte to get the actual bitfield value. */
143 *bitfield = (USHORT)((tlv_data[1] << 8) + tlv_data[0]);
144
145
146 return(NX_SECURE_X509_SUCCESS);
147 }
148
149