1414
1515#include < utility/SElementArduinoCloudCertificate.h>
1616
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+
1750int SElementArduinoCloudCertificate::write (SecureElement & se, ECP256Certificate & cert, const SElementArduinoCloudSlot certSlot)
1851{
1952#if defined(SECURE_ELEMENT_IS_SE050) || defined(SECURE_ELEMENT_IS_SOFTSE)
@@ -73,10 +106,10 @@ int SElementArduinoCloudCertificate::read(SecureElement & se, ECP256Certificate
73106 }
74107
75108 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 );
80113
81114 if (!cert.setPublicKey (publicKey, ECP256_CERT_PUBLIC_KEY_LENGTH)) {
82115 return 0 ;
@@ -92,3 +125,68 @@ int SElementArduinoCloudCertificate::read(SecureElement & se, ECP256Certificate
92125#endif
93126 return 1 ;
94127}
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