Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <NTPClient.h>
- #include <WiFiUdp.h>
- #include <WiFi.h>
- #include "mbedtls/md.h"
- #include <mbedtls/pk.h>
- #include <mbedtls/error.h>
- #include <mbedtls/entropy.h>
- #include <mbedtls/ctr_drbg.h>
- #include <base64.h>
- #include "base64.hpp"
- #include <ArduinoJson.h>
- //The device name
- #define DEVICE_NAME "a name"
- //The SSID of your WiFi network.
- #define SSID "a ssid"
- //The password to access your WiFi network.
- #define WIFIPASSWORD "a password"
- String ecc_priv = \
- "-----BEGIN EC PRIVATE KEY-----\r\n" \
- "MHcCAQEEI.......................................................\r\n" \
- "................................................................\r\n" \
- ".................................\r\n" \
- "-----END EC PRIVATE KEY-----";
- String ecc_pub = \
- "-----BEGIN PUBLIC KEY-----\r\n" \
- "MFkwEw.........................................................\r\n" \
- "...........................................................\r\n" \
- "-----END PUBLIC KEY-----";
- WiFiUDP ntpUDP;
- NTPClient timeClient(ntpUDP);
- String extractHeader(String _token){
- String result;
- int first = _token.indexOf(".");
- result = _token.substring(0,first);
- return result;
- }
- String extractPayload(String _token){
- String result;
- int first = _token.indexOf(".");
- int second = _token.indexOf(".", first+1);
- result = _token.substring(first+1,second);
- return result;
- }
- String extractSignature(String _token){
- String result;
- int first = _token.indexOf(".");
- int second = _token.indexOf(".", first+1);
- result = _token.substring(second+1);
- return result;
- }
- String extractHeaderAndPayload(String _token){
- String result;
- int first = _token.indexOf(".");
- int second = _token.indexOf(".", first+1);
- result = _token.substring(0, second);
- return result;
- }
- static char* mbedtlsError(int errnum) {
- static char buffer[200];
- mbedtls_strerror(errnum, buffer, sizeof(buffer));
- return buffer;
- }
- bool verifyJWT(String _token){
- timeClient.update();
- int ts = timeClient.getEpochTime();
- byte *pkeybuffer = (byte*)malloc((ecc_pub.length()+1)*sizeof(byte));
- ecc_pub.getBytes(pkeybuffer, ecc_pub.length() + 1);
- mbedtls_pk_context pk_context;
- mbedtls_pk_init(&pk_context);
- int rc = mbedtls_pk_parse_public_key(&pk_context, pkeybuffer, ecc_pub.length() + 1);
- if (rc != 0) {
- printf("Failed to mbedtls_pk_parse_public_key: %d (-0x%x): %s\n", rc, -rc, mbedtlsError(rc));
- }
- free(pkeybuffer);
- String headerandpayload = extractHeaderAndPayload(_token);
- byte *headerandpayloadbytes = (byte*)malloc((headerandpayload.length()+1)*sizeof(byte));
- headerandpayload.getBytes(headerandpayloadbytes, headerandpayload.length() + 1);
- String signature = extractSignature(_token);
- signature.replace('-','+');
- signature.replace('_','/');
- while(signature.length() % 3 != 0){
- signature += "=";
- }
- byte *signatureb64bytes = (byte*)malloc((signature.length()+1)*sizeof(byte));
- signature.getBytes(signatureb64bytes, signature.length() + 1);
- unsigned int siglength = decode_base64_length(signatureb64bytes, signature.length());
- byte *signaturebytes = (byte*)malloc((siglength)*sizeof(byte));
- decode_base64(signatureb64bytes, signature.length(), signaturebytes);
- free(signatureb64bytes);
- uint8_t digest[32];
- int rcmd = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), headerandpayloadbytes, headerandpayload.length(), digest);
- if (rcmd != 0) {
- printf("Failed to mbedtls_md: %d (-0x%x): %s\n", rc, -rc, mbedtlsError(rc));
- }
- free(headerandpayloadbytes);
- int ret = mbedtls_pk_verify(&pk_context, MBEDTLS_MD_SHA256, digest, sizeof(digest), signaturebytes, siglength);
- if (ret != 0) {
- printf("Failed to mbedtls_pk_verify: %d (-0x%x): %s\n", rc, -rc, mbedtlsError(rc));
- }
- free(signaturebytes);
- mbedtls_pk_free(&pk_context);
- String b64header = extractHeader(_token);
- b64header.replace('-','+');
- b64header.replace('_','/');
- while(b64header.length() % 3 != 0){
- b64header += "=";
- }
- byte *headerb64bytes = (byte*)malloc((b64header.length()+1)*sizeof(byte));
- b64header.getBytes(headerb64bytes, b64header.length()+1);
- unsigned int headerlength = decode_base64_length(headerb64bytes, b64header.length());
- byte *headerbytes = (byte*)malloc((headerlength+1)*sizeof(byte));
- unsigned int hl = decode_base64(headerb64bytes, headerbytes);
- headerbytes[hl] = '\0';
- String headerstring = String((char *)headerbytes);
- DynamicJsonDocument headerdoc(128);
- deserializeJson(headerdoc, headerstring);
- String alg = headerdoc["alg"];
- String typ = headerdoc["typ"];
- headerdoc.clear();
- free(headerb64bytes);
- free(headerbytes);
- String b64payload = extractPayload(_token);
- b64payload.replace('-','+');
- b64payload.replace('_','/');
- while(b64payload.length() % 3 != 0){
- b64payload += "=";
- }
- byte *payloadb64bytes = (byte*)malloc((b64payload.length()+1)*sizeof(byte));
- b64payload.getBytes(payloadb64bytes, b64payload.length()+1);
- unsigned int payloadlength = decode_base64_length(payloadb64bytes, b64payload.length());
- byte *payloadbytes = (byte*)malloc((payloadlength+1)*sizeof(byte));
- unsigned int pl = decode_base64(payloadb64bytes, payloadbytes);
- payloadbytes[pl] = '\0';
- String payloadstring = String((char *)payloadbytes);
- DynamicJsonDocument payloaddoc(128);
- deserializeJson(payloaddoc, payloadstring);
- String exp = payloaddoc["exp"];
- int expint = exp.toInt();
- String aud = payloaddoc["aud"];
- payloaddoc.clear();
- free(payloadb64bytes);
- free(payloadbytes);
- if(alg != "ES256"){
- return false;
- }
- if(expint < ts){
- return false;
- }
- if(typ != "JWT"){
- return false;
- }
- if(ret != 0){
- return false;
- }
- return true;
- }
- String createJWT() {
- String header = "{\"alg\":\"ES256\",\"typ\":\"JWT\"}";
- String base64Header = base64::encode(header);
- timeClient.update();
- int ts = timeClient.getEpochTime();
- uint32_t iat = ts;
- uint32_t exp = iat + 60*60;
- String payload = "{\"iat\":" + String(iat) + ",\"exp\":" + String(exp)+"}";
- String base64Payload = base64::encode(payload);
- String headerAndPayload = base64Header + "." + base64Payload;
- headerAndPayload.replace('+','-');
- headerAndPayload.replace('/','_');
- headerAndPayload.replace("=","");
- byte *keybuffer = (byte*)malloc((ecc_priv.length()+1)*sizeof(byte));
- ecc_priv.getBytes(keybuffer, ecc_priv.length() + 1);
- mbedtls_pk_context pk_context;
- mbedtls_pk_init(&pk_context);
- int rc = mbedtls_pk_parse_key(&pk_context, keybuffer, ecc_priv.length() + 1, NULL, 0);
- if (rc != 0) {
- printf("Failed to mbedtls_pk_parse_key: %d (-0x%x): %s\n", rc, -rc, mbedtlsError(rc));
- return "SHIT";
- }
- free(keybuffer);
- mbedtls_entropy_context entropy;
- mbedtls_ctr_drbg_context ctr_drbg;
- mbedtls_ctr_drbg_init(&ctr_drbg);
- mbedtls_entropy_init(&entropy);
- const char* pers="some entropy";
- mbedtls_ctr_drbg_seed(
- &ctr_drbg,
- mbedtls_entropy_func,
- &entropy,
- (const unsigned char*)pers,
- strlen(pers));
- byte *headerAndPayloadbytes = (byte*)malloc((headerAndPayload.length()+1)*sizeof(byte));
- headerAndPayload.getBytes(headerAndPayloadbytes, headerAndPayload.length() + 1);
- uint8_t digest[32];
- rc = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), headerAndPayloadbytes, headerAndPayload.length(), digest);
- if (rc != 0) {
- printf("Failed to mbedtls_md: %d (-0x%x): %s\n", rc, -rc, mbedtlsError(rc));
- }
- free(headerAndPayloadbytes);
- byte *oBuf = (byte*)malloc(5000*sizeof(byte));
- size_t retSize;
- rc = mbedtls_pk_sign(&pk_context, MBEDTLS_MD_SHA256, digest, sizeof(digest), oBuf, &retSize, mbedtls_ctr_drbg_random, &ctr_drbg);
- if (rc != 0) {
- printf("Failed to mbedtls_pk_sign: %d (-0x%x): %s\n", rc, -rc, mbedtlsError(rc));
- }
- unsigned int osize = encode_base64_length(retSize);
- byte *output = (byte*)malloc((osize+1)*sizeof(byte));
- encode_base64(oBuf, retSize, output);
- String sig = String((char*)output);
- free(output);
- sig.replace('+','-');
- sig.replace('/','_');
- sig.replace("=","");
- String completejwt = headerAndPayload + "." + sig;
- mbedtls_ctr_drbg_free( &ctr_drbg );
- mbedtls_entropy_free( &entropy );
- mbedtls_pk_free(&pk_context);
- free(oBuf);
- return completejwt;
- }
- void setup() {
- Serial.begin(115200);
- WiFi.mode(WIFI_STA);
- WiFi.hostname(DEVICE_NAME);
- WiFi.begin(SSID, WIFIPASSWORD);
- WiFi.setAutoReconnect(true);
- while (WiFi.waitForConnectResult() != WL_CONNECTED) {
- delay(5000);
- ESP.restart();
- }
- }
- void loop() {
- String token = createJWT();
- Serial.println(token);
- bool verified = verifyJWT(token);
- Serial.println(verified);
- delay(5000);
- }
Add Comment
Please, Sign In to add comment