Skip to content

Commit 1e3b023

Browse files
committed
Use ECCX08 slot to store Authority Key Identifier, and request in provisioning sketch
1 parent 9966adb commit 1e3b023

File tree

4 files changed

+77
-51
lines changed

4 files changed

+77
-51
lines changed

examples/utility/Provisioning/Provisioning.ino

+21-17
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
#include <utility/ECCX08TLSConfig.h>
44

55
#include <ArduinoBearSSL.h>
6-
#include <utility/ECCX08.h>
6+
#include <ArduinoECCX08.h>
77

8-
const int keySlot = 0;
9-
const int compressedCertSlot = 10;
10-
const int serialNumberSlot = 11;
11-
const int thingIdSlot = 12;
8+
const int keySlot = 0;
9+
const int compressedCertSlot = 10;
10+
const int serialNumberSlot = 11;
11+
const int authorityKeyIdentifierSlot = 12;
12+
const int thingIdSlot = 13;
1213

1314
void setup() {
1415
Serial.begin(9600);
@@ -68,37 +69,41 @@ void setup() {
6869
Serial.println();
6970
Serial.println(csr);
7071

71-
String thingId = promptAndReadLine("Please enter the thing id: ");
72-
String issueYear = promptAndReadLine("Please enter the issue year of the certificate (2000 - 2031): ");
73-
String issueMonth = promptAndReadLine("Please enter the issue month of the certificate (1 - 12): ");
74-
String issueDay = promptAndReadLine("Please enter the issue day of the certificate (1 - 31): ");
75-
String issueHour = promptAndReadLine("Please enter the issue hour of the certificate (0 - 23): ");
76-
String expireYears = promptAndReadLine("Please enter how many years the certificate is valid for (0 - 31): ");
77-
String serialNumber = promptAndReadLine("Please enter the certificates serial number: ");
78-
String signature = promptAndReadLine("Please enter the certificates signature: ");
72+
String thingId = promptAndReadLine("Please enter the thing id: ");
73+
String issueYear = promptAndReadLine("Please enter the issue year of the certificate (2000 - 2031): ");
74+
String issueMonth = promptAndReadLine("Please enter the issue month of the certificate (1 - 12): ");
75+
String issueDay = promptAndReadLine("Please enter the issue day of the certificate (1 - 31): ");
76+
String issueHour = promptAndReadLine("Please enter the issue hour of the certificate (0 - 23): ");
77+
String expireYears = promptAndReadLine("Please enter how many years the certificate is valid for (0 - 31): ");
78+
String serialNumber = promptAndReadLine("Please enter the certificates serial number: ");
79+
String authorityKeyIdentifier = promptAndReadLine("Please enter the certificates authority key identifier: ");
80+
String signature = promptAndReadLine("Please enter the certificates signature: ");
7981

8082
serialNumber.toUpperCase();
8183
signature.toUpperCase();
8284

8385
byte thingIdBytes[72];
8486
byte serialNumberBytes[16];
87+
byte authorityKeyIdentifierBytes[20];
8588
byte signatureBytes[64];
8689

8790
thingId.getBytes(thingIdBytes, sizeof(thingIdBytes));
8891
hexStringToBytes(serialNumber, serialNumberBytes, sizeof(serialNumberBytes));
89-
hexStringToBytes(signature, signatureBytes, 64);
92+
hexStringToBytes(authorityKeyIdentifier, authorityKeyIdentifierBytes, sizeof(authorityKeyIdentifierBytes));
93+
hexStringToBytes(signature, signatureBytes, sizeof(signatureBytes));
9094

9195
if (!ECCX08.writeSlot(thingIdSlot, thingIdBytes, sizeof(thingIdBytes))) {
9296
Serial.println("Error storing thing id!");
9397
while (1);
9498
}
9599

96-
if (!ECCX08Cert.beginStorage(compressedCertSlot, serialNumberSlot)) {
100+
if (!ECCX08Cert.beginStorage(compressedCertSlot, serialNumberSlot, authorityKeyIdentifierSlot)) {
97101
Serial.println("Error starting ECCX08 storage!");
98102
while (1);
99103
}
100104

101105
ECCX08Cert.setSignature(signatureBytes);
106+
ECCX08Cert.setAuthorityKeyIdentifier(authorityKeyIdentifierBytes);
102107
ECCX08Cert.setSerialNumber(serialNumberBytes);
103108
ECCX08Cert.setIssueYear(issueYear.toInt());
104109
ECCX08Cert.setIssueMonth(issueMonth.toInt());
@@ -111,7 +116,7 @@ void setup() {
111116
while (1);
112117
}
113118

114-
if (!ECCX08Cert.beginReconstruction(keySlot, compressedCertSlot, serialNumberSlot)) {
119+
if (!ECCX08Cert.beginReconstruction(keySlot, compressedCertSlot, serialNumberSlot, authorityKeyIdentifierSlot)) {
115120
Serial.println("Error starting ECCX08 cert reconstruction!");
116121
while (1);
117122
}
@@ -189,4 +194,3 @@ void hexStringToBytes(const String& in, byte out[], int length) {
189194
out[outLength++] = (highByte << 4) | lowByte;
190195
}
191196
}
192-

src/ArduinoCloud.cpp

+6-11
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77

88
const static char server[] = "a19g5nbe27wn47.iot.us-east-1.amazonaws.com"; //"xxxxxxxxxxxxxx.iot.xx-xxxx-x.amazonaws.com";
99

10-
const static int keySlot = 0;
11-
const static int compressedCertSlot = 10;
12-
const static int serialNumberSlot = 11;
13-
const static int thingIdSlot = 12;
10+
const static int keySlot = 0;
11+
const static int compressedCertSlot = 10;
12+
const static int serialNumberSlot = 11;
13+
const static int authorityKeyIdentifierSlot = 12;
14+
const static int thingIdSlot = 13;
1415

1516
ArduinoCloudClass::ArduinoCloudClass() :
1617
_bearSslClient(NULL),
@@ -38,7 +39,7 @@ int ArduinoCloudClass::begin(Client& net)
3839
}
3940
_id = (char*)thingIdBytes;
4041

41-
if (!ECCX08Cert.beginReconstruction(keySlot, compressedCertSlot, serialNumberSlot)) {
42+
if (!ECCX08Cert.beginReconstruction(keySlot, compressedCertSlot, serialNumberSlot, authorityKeyIdentifierSlot)) {
4243
return 0;
4344
}
4445

@@ -48,12 +49,6 @@ int ArduinoCloudClass::begin(Client& net)
4849
ECCX08Cert.setIssuerOrganizationalUnitName("IT");
4950
ECCX08Cert.setIssuerCommonName("Arduino");
5051

51-
const byte authorityKeyIdentifier[20] = {
52-
0xb2, 0xed, 0xef, 0xed, 0x3b, 0xbf, 0xc7, 0x71, 0x75, 0x24, 0x33, 0xd1, 0xae, 0x8b, 0x54, 0xed, 0x97, 0x14, 0x7a, 0x1d
53-
};
54-
55-
ECCX08Cert.setAuthorityKeyIdentifier(authorityKeyIdentifier);
56-
5752
if (!ECCX08Cert.endReconstruction()) {
5853
return 0;
5954
}

src/utility/ECCX08Cert.cpp

+43-14
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ struct __attribute__((__packed__)) CompressedCert {
1818
byte unused[5];
1919
};
2020

21-
#define SERIAL_NUMBER_LENGTH 16
21+
#define SERIAL_NUMBER_LENGTH 16
22+
#define AUTHORITY_KEY_IDENTIFIER_LENGTH 20
2223

2324
static String base64Encode(const byte in[], unsigned int length, const char* prefix, const char* suffix)
2425
{
@@ -73,7 +74,7 @@ ECCX08CertClass::ECCX08CertClass() :
7374
_keySlot(-1),
7475
_compressedCertSlot(-1),
7576
_serialNumberSlot(-1),
76-
_authorityKeyIdentifier(NULL),
77+
_authorityKeyIdentifierSlot(-1),
7778
_bytes(NULL),
7879
_length(0)
7980
{
@@ -185,7 +186,7 @@ String ECCX08CertClass::endCSR()
185186
return base64Encode(csr, csrLen + csrHeaderLen, "-----BEGIN CERTIFICATE REQUEST-----\n", "\n-----END CERTIFICATE REQUEST-----\n");
186187
}
187188

188-
int ECCX08CertClass::beginStorage(int compressedCertSlot, int serialNumberSlot)
189+
int ECCX08CertClass::beginStorage(int compressedCertSlot, int serialNumberSlot, int authorityKeyIdentifierSlot)
189190
{
190191
if (compressedCertSlot < 8 || compressedCertSlot > 15) {
191192
return 0;
@@ -195,8 +196,15 @@ int ECCX08CertClass::beginStorage(int compressedCertSlot, int serialNumberSlot)
195196
return 0;
196197
}
197198

199+
if (authorityKeyIdentifierSlot > -1) {
200+
if (authorityKeyIdentifierSlot < 8 || authorityKeyIdentifierSlot > 15) {
201+
return 0;
202+
}
203+
}
204+
198205
_compressedCertSlot = compressedCertSlot;
199206
_serialNumberSlot = serialNumberSlot;
207+
_authorityKeyIdentifierSlot = authorityKeyIdentifierSlot;
200208

201209
memset(_temp, 0x00, sizeof(_temp));
202210

@@ -256,11 +264,16 @@ void ECCX08CertClass::setExpireYears(int expireYears)
256264
compressedCert->dates[2] |= expireYears;
257265
}
258266

259-
void ECCX08CertClass::setSerialNumber(byte serialNumber[])
267+
void ECCX08CertClass::setSerialNumber(const byte serialNumber[])
260268
{
261269
memcpy(&_temp[72], serialNumber, SERIAL_NUMBER_LENGTH);
262270
}
263271

272+
void ECCX08CertClass::setAuthorityKeyIdentifier(const byte authorityKeyIdentifier[])
273+
{
274+
memcpy(&_temp[88], authorityKeyIdentifier, AUTHORITY_KEY_IDENTIFIER_LENGTH);
275+
}
276+
264277
int ECCX08CertClass::endStorage()
265278
{
266279
if (!ECCX08.writeSlot(_compressedCertSlot, &_temp[0], 72)) {
@@ -271,10 +284,14 @@ int ECCX08CertClass::endStorage()
271284
return 0;
272285
}
273286

287+
if (!ECCX08.writeSlot(_authorityKeyIdentifierSlot, &_temp[88], AUTHORITY_KEY_IDENTIFIER_LENGTH)) {
288+
return 0;
289+
}
290+
274291
return 1;
275292
}
276293

277-
int ECCX08CertClass::beginReconstruction(int keySlot, int compressedCertSlot, int serialNumberSlot)
294+
int ECCX08CertClass::beginReconstruction(int keySlot, int compressedCertSlot, int serialNumberSlot, int authorityKeyIdentifierSlot)
278295
{
279296
if (keySlot < 0 || keySlot > 8) {
280297
return 0;
@@ -288,9 +305,16 @@ int ECCX08CertClass::beginReconstruction(int keySlot, int compressedCertSlot, in
288305
return 0;
289306
}
290307

308+
if (authorityKeyIdentifierSlot > -1) {
309+
if (authorityKeyIdentifierSlot < 8 || authorityKeyIdentifierSlot > 15) {
310+
return 0;
311+
}
312+
}
313+
291314
_keySlot = keySlot;
292315
_compressedCertSlot = compressedCertSlot;
293316
_serialNumberSlot = serialNumberSlot;
317+
_authorityKeyIdentifierSlot = authorityKeyIdentifierSlot;
294318

295319
return 1;
296320
}
@@ -300,6 +324,7 @@ int ECCX08CertClass::endReconstruction()
300324
byte publicKey[64];
301325
struct CompressedCert compressedCert;
302326
byte serialNumber[SERIAL_NUMBER_LENGTH];
327+
byte authorityKeyIdentifier[AUTHORITY_KEY_IDENTIFIER_LENGTH];
303328

304329
if (!ECCX08.generatePublicKey(_keySlot, publicKey)) {
305330
return 0;
@@ -313,6 +338,11 @@ int ECCX08CertClass::endReconstruction()
313338
return 0;
314339
}
315340

341+
if (_authorityKeyIdentifierSlot > -1 &&
342+
!ECCX08.readSlot(_authorityKeyIdentifierSlot, authorityKeyIdentifier, sizeof(authorityKeyIdentifier))) {
343+
return 0;
344+
}
345+
316346
int serialNumberLen = serialNumberLength(serialNumber);
317347

318348
int issuerLen = issuerOrSubjectLength(_issuerCountryName,
@@ -335,7 +365,11 @@ int ECCX08CertClass::endReconstruction()
335365

336366
int publicKeyLen = publicKeyLength();
337367

338-
int authorityKeyIdentifierLen = authorityKeyIdentifierLength(_authorityKeyIdentifier);
368+
int authorityKeyIdentifierLen = 0;
369+
370+
if (_authorityKeyIdentifierSlot > -1) {
371+
authorityKeyIdentifierLen = authorityKeyIdentifierLength();
372+
}
339373

340374
int signatureLen = signatureLength(compressedCert.signature);
341375

@@ -422,7 +456,7 @@ int ECCX08CertClass::endReconstruction()
422456
out += publicKeyLen;
423457

424458
if (authorityKeyIdentifierLen) {
425-
appendAuthorityKeyIdentifier(_authorityKeyIdentifier, out);
459+
appendAuthorityKeyIdentifier(authorityKeyIdentifier, out);
426460
out += authorityKeyIdentifierLen;
427461
} else {
428462
// null sequence
@@ -509,11 +543,6 @@ void ECCX08CertClass::setSubjectCommonName(const String& commonName)
509543
_subjectCommonName = commonName;
510544
}
511545

512-
void ECCX08CertClass::setAuthorityKeyIdentifier(const byte authorityKeyIdentifier[])
513-
{
514-
_authorityKeyIdentifier = authorityKeyIdentifier;
515-
}
516-
517546
int ECCX08CertClass::versionLength()
518547
{
519548
return 3;
@@ -566,9 +595,9 @@ int ECCX08CertClass::publicKeyLength()
566595
return (2 + 2 + 9 + 10 + 4 + 64);
567596
}
568597

569-
int ECCX08CertClass::authorityKeyIdentifierLength(const byte authorityKeyIdentifier[])
598+
int ECCX08CertClass::authorityKeyIdentifierLength()
570599
{
571-
return (authorityKeyIdentifier == NULL) ? 0 : 37;
600+
return 37;
572601
}
573602

574603
int ECCX08CertClass::signatureLength(const byte signature[])

src/utility/ECCX08Cert.h

+7-9
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,18 @@ class ECCX08CertClass {
1212
int beginCSR(int keySlot, bool newPrivateKey = true);
1313
String endCSR();
1414

15-
int beginStorage(int compressedCertSlot, int serialNumberSlot);
15+
int beginStorage(int compressedCertSlot, int serialNumberSlot, int authorityKeyIdentifierSlot);
1616
void setSignature(byte signature[]);
1717
void setIssueYear(int issueYear);
1818
void setIssueMonth(int issueMonth);
1919
void setIssueDay(int issueDay);
2020
void setIssueHour(int issueHour);
2121
void setExpireYears(int expireYears);
22-
void setSerialNumber(byte serialNumber[]);
22+
void setSerialNumber(const byte serialNumber[]);
23+
void setAuthorityKeyIdentifier(const byte authorityKeyIdentifier[]);
2324
int endStorage();
2425

25-
int beginReconstruction(int keySlot, int compressedCertSlot, int serialNumberSlot);
26+
int beginReconstruction(int keySlot, int compressedCertSlot, int serialNumberSlot, int authorityKeyIdentifierSlot);
2627
int endReconstruction();
2728

2829
byte* bytes();
@@ -42,8 +43,6 @@ class ECCX08CertClass {
4243
void setSubjectOrganizationalUnitName(const String& organizationalUnitName);
4344
void setSubjectCommonName(const String& commonName);
4445

45-
void setAuthorityKeyIdentifier(const byte authorityKeyIdentifier[]);
46-
4746
private:
4847
int versionLength();
4948

@@ -56,7 +55,7 @@ class ECCX08CertClass {
5655

5756
int publicKeyLength();
5857

59-
int authorityKeyIdentifierLength(const byte authorityKeyIdentifier[]);
58+
int authorityKeyIdentifierLength();
6059

6160
int signatureLength(const byte signature[]);
6261

@@ -94,6 +93,7 @@ class ECCX08CertClass {
9493
int _keySlot;
9594
int _compressedCertSlot;
9695
int _serialNumberSlot;
96+
int _authorityKeyIdentifierSlot;
9797

9898
String _issuerCountryName;
9999
String _issuerStateProvinceName;
@@ -109,9 +109,7 @@ class ECCX08CertClass {
109109
String _subjectOrganizationalUnitName;
110110
String _subjectCommonName;
111111

112-
const byte* _authorityKeyIdentifier;
113-
114-
byte _temp[88];
112+
byte _temp[108];
115113
byte* _bytes;
116114
int _length;
117115
};

0 commit comments

Comments
 (0)