14
14
15
15
#include < utility/SElementArduinoCloudCertificate.h>
16
16
17
+ /* *****************************************************************************
18
+ * LOCAL MODULE FUNCTIONS
19
+ ******************************************************************************/
20
+
21
+ static void hexStringToBytes (String in, byte out[], int length) {
22
+ int inLength = in.length ();
23
+ in.toUpperCase ();
24
+ int outLength = 0 ;
25
+
26
+ for (int i = 0 ; i < inLength && outLength < length; i += 2 ) {
27
+ char highChar = in[i];
28
+ char lowChar = in[i + 1 ];
29
+
30
+ byte highByte = (highChar <= ' 9' ) ? (highChar - ' 0' ) : (highChar + 10 - ' A' );
31
+ byte lowByte = (lowChar <= ' 9' ) ? (lowChar - ' 0' ) : (lowChar + 10 - ' A' );
32
+
33
+ out[outLength++] = (highByte << 4 ) | (lowByte & 0xF );
34
+ }
35
+ }
36
+
37
+ /* *****************************************************************************
38
+ * STATIC MEMBER DEFINITIONS
39
+ ******************************************************************************/
40
+
41
+ const char constexpr SElementArduinoCloudCertificate::SEACC_ISSUER_COUNTRY_NAME[];
42
+ const char constexpr SElementArduinoCloudCertificate::SEACC_ISSUER_ORGANIZATION_NAME[];
43
+ const char constexpr SElementArduinoCloudCertificate::SEACC_ISSUER_ORGANIZATIONAL_UNIT_NAME[];
44
+ const char constexpr SElementArduinoCloudCertificate::SEACC_ISSUER_COMMON_NAME[];
45
+
46
+ /* *****************************************************************************
47
+ * PUBLIC MEMBER FUNCTIONS
48
+ ******************************************************************************/
49
+
17
50
int SElementArduinoCloudCertificate::write (SecureElement & se, ECP256Certificate & cert, const SElementArduinoCloudSlot certSlot)
18
51
{
19
52
#if defined(SECURE_ELEMENT_IS_SE050) || defined(SECURE_ELEMENT_IS_SOFTSE)
@@ -73,10 +106,10 @@ int SElementArduinoCloudCertificate::read(SecureElement & se, ECP256Certificate
73
106
}
74
107
75
108
cert.setSubjectCommonName (deviceId);
76
- cert.setIssuerCountryName (" US " );
77
- cert.setIssuerOrganizationName (" Arduino LLC US " );
78
- cert.setIssuerOrganizationalUnitName (" IT " );
79
- cert.setIssuerCommonName (" Arduino " );
109
+ cert.setIssuerCountryName (SEACC_ISSUER_COUNTRY_NAME );
110
+ cert.setIssuerOrganizationName (SEACC_ISSUER_ORGANIZATION_NAME );
111
+ cert.setIssuerOrganizationalUnitName (SEACC_ISSUER_ORGANIZATIONAL_UNIT_NAME );
112
+ cert.setIssuerCommonName (SEACC_ISSUER_COMMON_NAME );
80
113
81
114
if (!cert.setPublicKey (publicKey, ECP256_CERT_PUBLIC_KEY_LENGTH)) {
82
115
return 0 ;
@@ -92,3 +125,68 @@ int SElementArduinoCloudCertificate::read(SecureElement & se, ECP256Certificate
92
125
#endif
93
126
return 1 ;
94
127
}
128
+
129
+ int SElementArduinoCloudCertificate::signatureCompare (const byte * signatureA, const String & signatureB)
130
+ {
131
+ byte signatureBytes[ECP256_CERT_SIGNATURE_LENGTH];
132
+
133
+ if (signatureB.length () == 0 || signatureA == nullptr ) {
134
+ DEBUG_ERROR (" SEACC::%s input params error." , __FUNCTION__);
135
+ return -1 ;
136
+ }
137
+
138
+ hexStringToBytes (signatureB, signatureBytes, sizeof (signatureBytes));
139
+
140
+ /* If authorityKeyId are matching there is no need to rebuild*/
141
+ if (memcmp (signatureBytes, signatureA , sizeof (signatureBytes)) == 0 ) {
142
+ DEBUG_VERBOSE (" SEACC::%s signatures are equal" , __FUNCTION__);
143
+ return 0 ;
144
+ }
145
+ return 1 ;
146
+ }
147
+
148
+ int SElementArduinoCloudCertificate::rebuild (
149
+ SecureElement & se, ECP256Certificate & cert, const String & deviceId,
150
+ const String & notBefore, const String & notAfter, const String & serialNumber,
151
+ const String & authorityKeyIdentifier, const String & signature,
152
+ const SElementArduinoCloudSlot keySlot)
153
+ {
154
+ byte serialNumberBytes[ECP256_CERT_SERIAL_NUMBER_LENGTH];
155
+ byte authorityKeyIdentifierBytes[ECP256_CERT_AUTHORITY_KEY_ID_LENGTH];
156
+ byte signatureBytes[ECP256_CERT_SIGNATURE_LENGTH];
157
+
158
+ if (!deviceId.length () || !notBefore.length () || !notAfter.length () || !serialNumber.length () || !authorityKeyIdentifier.length () || !signature.length () ) {
159
+ DEBUG_ERROR (" SEACC::%s input params error." , __FUNCTION__);
160
+ return 0 ;
161
+ }
162
+
163
+ hexStringToBytes (serialNumber, serialNumberBytes, sizeof (serialNumberBytes));
164
+ hexStringToBytes (authorityKeyIdentifier, authorityKeyIdentifierBytes, sizeof (authorityKeyIdentifierBytes));
165
+ hexStringToBytes (signature, signatureBytes, sizeof (signatureBytes));
166
+
167
+ if (!cert.begin ()) {
168
+ DEBUG_ERROR (" SEACC::%s cert begin error" , __FUNCTION__);
169
+ return -1 ;
170
+ }
171
+
172
+ cert.setSubjectCommonName (deviceId);
173
+ cert.setIssuerCountryName (SEACC_ISSUER_COUNTRY_NAME);
174
+ cert.setIssuerOrganizationName (SEACC_ISSUER_ORGANIZATION_NAME);
175
+ cert.setIssuerOrganizationalUnitName (SEACC_ISSUER_ORGANIZATIONAL_UNIT_NAME);
176
+ cert.setIssuerCommonName (SEACC_ISSUER_COMMON_NAME);
177
+ cert.setSignature (signatureBytes, sizeof (signatureBytes));
178
+ cert.setAuthorityKeyId (authorityKeyIdentifierBytes, sizeof (authorityKeyIdentifierBytes));
179
+ cert.setSerialNumber (serialNumberBytes, sizeof (serialNumberBytes));
180
+ cert.setIssueYear (notBefore.substring (0 ,4 ).toInt ());
181
+ cert.setIssueMonth (notBefore.substring (5 ,7 ).toInt ());
182
+ cert.setIssueDay (notBefore.substring (8 ,10 ).toInt ());
183
+ cert.setIssueHour (notBefore.substring (11 ,13 ).toInt ());
184
+ cert.setExpireYears (notAfter.substring (0 ,4 ).toInt () - notBefore.substring (0 ,4 ).toInt ());
185
+
186
+
187
+ if (!SElementCertificate::build (se, cert, static_cast <int >(keySlot))) {
188
+ DEBUG_ERROR (" SEACC::%s cert build error" , __FUNCTION__);
189
+ return -1 ;
190
+ }
191
+ return 1 ;
192
+ }
0 commit comments