Skip to content

Commit 71e5887

Browse files
committed
Share SElement Base64 functions
1 parent 72696f6 commit 71e5887

File tree

4 files changed

+129
-98
lines changed

4 files changed

+129
-98
lines changed

src/ECP256Certificate.cpp

+3-54
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
/* This is needed for memmem */
1616
#define _GNU_SOURCE
1717
#include <string.h>
18+
#include <utility/SElementBase64.h>
1819
#include "ECP256Certificate.h"
1920

2021
/******************************************************************************
@@ -29,58 +30,6 @@
2930
#define ASN1_SEQUENCE 0x30
3031
#define ASN1_SET 0x31
3132

32-
/******************************************************************************
33-
* LOCAL MODULE FUNCTIONS
34-
******************************************************************************/
35-
36-
static String base64Encode(const byte in[], unsigned int length, const char* prefix, const char* suffix) {
37-
static const char* CODES = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
38-
39-
int b;
40-
String out;
41-
42-
int reserveLength = 4 * ((length + 2) / 3) + ((length / 3 * 4) / 76) + strlen(prefix) + strlen(suffix);
43-
out.reserve(reserveLength);
44-
45-
if (prefix) {
46-
out += prefix;
47-
}
48-
49-
for (unsigned int i = 0; i < length; i += 3) {
50-
if (i > 0 && (i / 3 * 4) % 76 == 0) {
51-
out += '\n';
52-
}
53-
54-
b = (in[i] & 0xFC) >> 2;
55-
out += CODES[b];
56-
57-
b = (in[i] & 0x03) << 4;
58-
if (i + 1 < length) {
59-
b |= (in[i + 1] & 0xF0) >> 4;
60-
out += CODES[b];
61-
b = (in[i + 1] & 0x0F) << 2;
62-
if (i + 2 < length) {
63-
b |= (in[i + 2] & 0xC0) >> 6;
64-
out += CODES[b];
65-
b = in[i + 2] & 0x3F;
66-
out += CODES[b];
67-
} else {
68-
out += CODES[b];
69-
out += '=';
70-
}
71-
} else {
72-
out += CODES[b];
73-
out += "==";
74-
}
75-
}
76-
77-
if (suffix) {
78-
out += suffix;
79-
}
80-
81-
return out;
82-
}
83-
8433
/******************************************************************************
8534
* CTOR/DTOR
8635
******************************************************************************/
@@ -184,7 +133,7 @@ int ECP256Certificate::signCSR(byte * signature)
184133

185134
String ECP256Certificate::getCSRPEM()
186135
{
187-
return base64Encode(_certBuffer, _certBufferLen, "-----BEGIN CERTIFICATE REQUEST-----\n", "\n-----END CERTIFICATE REQUEST-----\n");
136+
return b64::encode(_certBuffer, _certBufferLen, "-----BEGIN CERTIFICATE REQUEST-----\n", "\n-----END CERTIFICATE REQUEST-----\n");
188137
}
189138

190139
int ECP256Certificate::buildCert()
@@ -323,7 +272,7 @@ int ECP256Certificate::signCert()
323272

324273
String ECP256Certificate::getCertPEM()
325274
{
326-
return base64Encode(_certBuffer, _certBufferLen, "-----BEGIN CERTIFICATE-----\n", "\n-----END CERTIFICATE-----\n");
275+
return b64::encode(_certBuffer, _certBufferLen, "-----BEGIN CERTIFICATE-----\n", "\n-----END CERTIFICATE-----\n");
327276
}
328277

329278
void ECP256Certificate::getDateFromCompressedData(DateInfo& date) {

src/utility/SElementBase64.cpp

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
This file is part of the Arduino_SecureElement library.
3+
4+
Copyright (c) 2024 Arduino SA
5+
6+
This Source Code Form is subject to the terms of the Mozilla Public
7+
License, v. 2.0. If a copy of the MPL was not distributed with this
8+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
11+
#include <utility/SElementBase64.h>
12+
13+
namespace arduino { namespace b64 {
14+
15+
String urlEncode(const byte in[], unsigned int length) {
16+
static const char* CODES = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=";
17+
18+
int b;
19+
String out;
20+
21+
int reserveLength = 4 * ((length + 2) / 3);
22+
out.reserve(reserveLength);
23+
24+
for (unsigned int i = 0; i < length; i += 3) {
25+
b = (in[i] & 0xFC) >> 2;
26+
out += CODES[b];
27+
28+
b = (in[i] & 0x03) << 4;
29+
if (i + 1 < length) {
30+
b |= (in[i + 1] & 0xF0) >> 4;
31+
out += CODES[b];
32+
b = (in[i + 1] & 0x0F) << 2;
33+
if (i + 2 < length) {
34+
b |= (in[i + 2] & 0xC0) >> 6;
35+
out += CODES[b];
36+
b = in[i + 2] & 0x3F;
37+
out += CODES[b];
38+
} else {
39+
out += CODES[b];
40+
}
41+
} else {
42+
out += CODES[b];
43+
}
44+
}
45+
46+
while (out.lastIndexOf('=') != -1) {
47+
out.remove(out.length() - 1);
48+
}
49+
50+
return out;
51+
}
52+
53+
String encode(const byte in[], unsigned int length, const char* prefix, const char* suffix) {
54+
static const char* CODES = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
55+
56+
int b;
57+
String out;
58+
59+
int reserveLength = 4 * ((length + 2) / 3) + ((length / 3 * 4) / 76) + strlen(prefix) + strlen(suffix);
60+
out.reserve(reserveLength);
61+
62+
if (prefix) {
63+
out += prefix;
64+
}
65+
66+
for (unsigned int i = 0; i < length; i += 3) {
67+
if (i > 0 && (i / 3 * 4) % 76 == 0) {
68+
out += '\n';
69+
}
70+
71+
b = (in[i] & 0xFC) >> 2;
72+
out += CODES[b];
73+
74+
b = (in[i] & 0x03) << 4;
75+
if (i + 1 < length) {
76+
b |= (in[i + 1] & 0xF0) >> 4;
77+
out += CODES[b];
78+
b = (in[i + 1] & 0x0F) << 2;
79+
if (i + 2 < length) {
80+
b |= (in[i + 2] & 0xC0) >> 6;
81+
out += CODES[b];
82+
b = in[i + 2] & 0x3F;
83+
out += CODES[b];
84+
} else {
85+
out += CODES[b];
86+
out += '=';
87+
}
88+
} else {
89+
out += CODES[b];
90+
out += "==";
91+
}
92+
}
93+
94+
if (suffix) {
95+
out += suffix;
96+
}
97+
98+
return out;
99+
}
100+
101+
}} // arduino::b64

src/utility/SElementBase64.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
This file is part of the Arduino_SecureElement library.
3+
4+
Copyright (c) 2024 Arduino SA
5+
6+
This Source Code Form is subject to the terms of the Mozilla Public
7+
License, v. 2.0. If a copy of the MPL was not distributed with this
8+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
11+
#pragma once
12+
13+
#include <Arduino.h>
14+
15+
namespace arduino { namespace b64 {
16+
17+
String urlEncode(const byte in[], unsigned int length);
18+
String encode(const byte in[], unsigned int length, const char* prefix, const char* suffix);
19+
20+
}} // arduino::b64

src/utility/SElementJWS.cpp

+5-44
Original file line numberDiff line numberDiff line change
@@ -13,48 +13,9 @@
1313
******************************************************************************/
1414

1515
#include <utility/SElementJWS.h>
16+
#include <utility/SElementBase64.h>
1617
#include <ArduinoECCX08.h>
1718
#include <utility/ASN1Utils.h>
18-
#include <utility/PEMUtils.h>
19-
20-
static String base64urlEncode(const byte in[], unsigned int length)
21-
{
22-
static const char* CODES = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=";
23-
24-
int b;
25-
String out;
26-
27-
int reserveLength = 4 * ((length + 2) / 3);
28-
out.reserve(reserveLength);
29-
30-
for (unsigned int i = 0; i < length; i += 3) {
31-
b = (in[i] & 0xFC) >> 2;
32-
out += CODES[b];
33-
34-
b = (in[i] & 0x03) << 4;
35-
if (i + 1 < length) {
36-
b |= (in[i + 1] & 0xF0) >> 4;
37-
out += CODES[b];
38-
b = (in[i + 1] & 0x0F) << 2;
39-
if (i + 2 < length) {
40-
b |= (in[i + 2] & 0xC0) >> 6;
41-
out += CODES[b];
42-
b = in[i + 2] & 0x3F;
43-
out += CODES[b];
44-
} else {
45-
out += CODES[b];
46-
}
47-
} else {
48-
out += CODES[b];
49-
}
50-
}
51-
52-
while (out.lastIndexOf('=') != -1) {
53-
out.remove(out.length() - 1);
54-
}
55-
56-
return out;
57-
}
5819

5920
String SElementJWS::publicKey(SecureElement & se, int slot, bool newPrivateKey)
6021
{
@@ -79,7 +40,7 @@ String SElementJWS::publicKey(SecureElement & se, int slot, bool newPrivateKey)
7940

8041
ASN1Utils.appendPublicKey(publicKey, out);
8142

82-
return PEMUtils.base64Encode(out, length, "-----BEGIN PUBLIC KEY-----\n", "\n-----END PUBLIC KEY-----\n");
43+
return b64::encode(out, length, "-----BEGIN PUBLIC KEY-----\n", "\n-----END PUBLIC KEY-----\n");
8344
}
8445

8546
String SElementJWS::sign(SecureElement & se, int slot, const char* header, const char* payload)
@@ -88,8 +49,8 @@ String SElementJWS::sign(SecureElement & se, int slot, const char* header, const
8849
return "";
8950
}
9051

91-
String encodedHeader = base64urlEncode((const byte*)header, strlen(header));
92-
String encodedPayload = base64urlEncode((const byte*)payload, strlen(payload));
52+
String encodedHeader = b64::urlEncode((const byte*)header, strlen(header));
53+
String encodedPayload = b64::urlEncode((const byte*)payload, strlen(payload));
9354

9455
String toSign;
9556
toSign.reserve(encodedHeader.length() + 1 + encodedPayload.length());
@@ -108,7 +69,7 @@ String SElementJWS::sign(SecureElement & se, int slot, const char* header, const
10869
return "";
10970
}
11071

111-
String encodedSignature = base64urlEncode(signature, sizeof(signature));
72+
String encodedSignature = b64::urlEncode(signature, sizeof(signature));
11273

11374
String result;
11475
result.reserve(toSign.length() + 1 + encodedSignature.length());

0 commit comments

Comments
 (0)