A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Wed Apr 01 12:48:52 2020 +0000
Revision:
24:cb43290fc439
Parent:
21:a6d6e26dd742
Added check so that if the client closes the TCP connection before the TLS connection is established then respond that we have finished and the TCP connection is to be closed.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 4:6a1d887f1cad 1 #include <stdint.h>
andrewboyson 4:6a1d887f1cad 2
andrewboyson 0:be515c9019e3 3 #include "base64.h"
andrewboyson 0:be515c9019e3 4 #include "log.h"
andrewboyson 10:e269fd7b9500 5 #include "rsa.h"
andrewboyson 0:be515c9019e3 6
andrewboyson 0:be515c9019e3 7 /*
andrewboyson 0:be515c9019e3 8 RSAPrivateKey ::= SEQUENCE {
andrewboyson 0:be515c9019e3 9 version INTEGER,
andrewboyson 0:be515c9019e3 10 modulus INTEGER, -- n
andrewboyson 0:be515c9019e3 11 publicExponent INTEGER, -- e
andrewboyson 0:be515c9019e3 12 privateExponent INTEGER, -- d
andrewboyson 0:be515c9019e3 13 prime1 INTEGER, -- p
andrewboyson 0:be515c9019e3 14 prime2 INTEGER, -- q
andrewboyson 0:be515c9019e3 15 exponent1 INTEGER, -- d mod (p-1)
andrewboyson 0:be515c9019e3 16 exponent2 INTEGER, -- d mod (q-1)
andrewboyson 0:be515c9019e3 17 coefficient INTEGER, -- (inverse of q) mod p
andrewboyson 0:be515c9019e3 18 otherPrimeInfos OtherPrimeInfos OPTIONAL
andrewboyson 0:be515c9019e3 19 */
andrewboyson 0:be515c9019e3 20
andrewboyson 4:6a1d887f1cad 21 uint8_t v [ 4]; //version
andrewboyson 4:6a1d887f1cad 22 uint8_t n [128]; //modulus
andrewboyson 4:6a1d887f1cad 23 uint8_t e [ 4]; //publicExponent
andrewboyson 4:6a1d887f1cad 24 uint8_t d [128]; //privateExponent
andrewboyson 4:6a1d887f1cad 25 uint8_t p [ 64]; //prime1
andrewboyson 4:6a1d887f1cad 26 uint8_t q [ 64]; //prime2
andrewboyson 4:6a1d887f1cad 27 uint8_t dp [ 64]; //exponent1 -- d mod (p-1)
andrewboyson 4:6a1d887f1cad 28 uint8_t dq [ 64]; //exponent2 -- d mod (q-1)
andrewboyson 4:6a1d887f1cad 29 uint8_t invq[ 64]; //coefficient -- (inverse of q) mod p
andrewboyson 0:be515c9019e3 30
andrewboyson 0:be515c9019e3 31 static const char* pNext;
andrewboyson 0:be515c9019e3 32 static const char* buffer =
andrewboyson 0:be515c9019e3 33 #include "pri-key.inc"
andrewboyson 0:be515c9019e3 34 ;
andrewboyson 0:be515c9019e3 35 static char readChar()
andrewboyson 0:be515c9019e3 36 {
andrewboyson 0:be515c9019e3 37 char c = *pNext;
andrewboyson 0:be515c9019e3 38 if (!c) return 0;
andrewboyson 0:be515c9019e3 39 pNext++;
andrewboyson 0:be515c9019e3 40 return c;
andrewboyson 0:be515c9019e3 41 }
andrewboyson 0:be515c9019e3 42 static int readLength()
andrewboyson 0:be515c9019e3 43 {
andrewboyson 0:be515c9019e3 44 int c = Base64ReadByte();
andrewboyson 0:be515c9019e3 45 if (c == -1) return -1; //EOF or an error
andrewboyson 0:be515c9019e3 46 if (c < 0x80) return c; //Single byte length
andrewboyson 0:be515c9019e3 47 if (c == 0x80) return -1; //indefinite form - do not use
andrewboyson 0:be515c9019e3 48 int numberOfBytes = c - 0x80;
andrewboyson 0:be515c9019e3 49 int len = 0;
andrewboyson 0:be515c9019e3 50 for (int i = 0; i < numberOfBytes; i++)
andrewboyson 0:be515c9019e3 51 {
andrewboyson 0:be515c9019e3 52 len <<= 8;
andrewboyson 0:be515c9019e3 53 c = Base64ReadByte();
andrewboyson 0:be515c9019e3 54 if (c == -1) return -1; //EOF or an error
andrewboyson 0:be515c9019e3 55 len |= c;
andrewboyson 0:be515c9019e3 56 }
andrewboyson 0:be515c9019e3 57 return len;
andrewboyson 0:be515c9019e3 58 }
andrewboyson 0:be515c9019e3 59 static int readSequence()
andrewboyson 0:be515c9019e3 60 {
andrewboyson 0:be515c9019e3 61 int c = Base64ReadByte();
andrewboyson 0:be515c9019e3 62 if (c == -1) return -1; //EOF or an error
andrewboyson 0:be515c9019e3 63 if (c != 0x30) return -1; //Not SEQUENCE type
andrewboyson 0:be515c9019e3 64 int len = readLength();
andrewboyson 0:be515c9019e3 65 return len;
andrewboyson 0:be515c9019e3 66 }
andrewboyson 4:6a1d887f1cad 67 static int readData(uint8_t* data, int size) //Reads the data from big-endian 'pem' format into little-endian 'bn' format
andrewboyson 0:be515c9019e3 68 {
andrewboyson 0:be515c9019e3 69 int c = Base64ReadByte();
andrewboyson 0:be515c9019e3 70 if (c == -1) return -1; //EOF or an error
andrewboyson 0:be515c9019e3 71 if (c != 0x02) return -1; //Not INTEGER type
andrewboyson 0:be515c9019e3 72 int pemLength = readLength();
andrewboyson 0:be515c9019e3 73 if (pemLength == -1) return -1; //EOF or an error
andrewboyson 0:be515c9019e3 74
andrewboyson 0:be515c9019e3 75 int finalLength = pemLength;
andrewboyson 0:be515c9019e3 76 for (int i = 0; i < pemLength; i++)
andrewboyson 0:be515c9019e3 77 {
andrewboyson 0:be515c9019e3 78 c = Base64ReadByte();
andrewboyson 0:be515c9019e3 79 if (c == -1) return -1; //EOF or an error
andrewboyson 0:be515c9019e3 80 if (!i && !c) //Don't add if this is the msb and that byte is zero but reduce the final length by 1
andrewboyson 0:be515c9019e3 81 {
andrewboyson 0:be515c9019e3 82 finalLength--;
andrewboyson 0:be515c9019e3 83 }
andrewboyson 0:be515c9019e3 84 else
andrewboyson 0:be515c9019e3 85 {
andrewboyson 0:be515c9019e3 86 data[pemLength - 1 - i] = c; //If pemLength is one too big then 'i' will also be one too big so the result is correct
andrewboyson 0:be515c9019e3 87 }
andrewboyson 0:be515c9019e3 88 }
andrewboyson 0:be515c9019e3 89 for (int i = finalLength; i < size; i++) data[i] = 0;
andrewboyson 0:be515c9019e3 90
andrewboyson 0:be515c9019e3 91 return finalLength + 1;
andrewboyson 0:be515c9019e3 92 }
andrewboyson 0:be515c9019e3 93 void PriKeyInit()
andrewboyson 0:be515c9019e3 94 {
andrewboyson 0:be515c9019e3 95 pNext = buffer;
andrewboyson 0:be515c9019e3 96 Base64ReadNextCharFunctionPointer = readChar;
andrewboyson 0:be515c9019e3 97
andrewboyson 0:be515c9019e3 98 int r = 0;
andrewboyson 0:be515c9019e3 99 r = Base64SkipLine(); if (r < 0) return;
andrewboyson 0:be515c9019e3 100 r = readSequence(); if (r < 0) return;
andrewboyson 0:be515c9019e3 101
andrewboyson 0:be515c9019e3 102 r = readData( v, sizeof( v)); if (r < 0) return;
andrewboyson 0:be515c9019e3 103 r = readData( n, sizeof( n)); if (r < 0) return;
andrewboyson 0:be515c9019e3 104 r = readData( e, sizeof( e)); if (r < 0) return;
andrewboyson 0:be515c9019e3 105 r = readData( d, sizeof( d)); if (r < 0) return;
andrewboyson 0:be515c9019e3 106 r = readData( p, sizeof( p)); if (r < 0) return;
andrewboyson 0:be515c9019e3 107 r = readData( q, sizeof( q)); if (r < 0) return;
andrewboyson 0:be515c9019e3 108 r = readData( dp, sizeof( dp)); if (r < 0) return;
andrewboyson 0:be515c9019e3 109 r = readData( dq, sizeof( dq)); if (r < 0) return;
andrewboyson 0:be515c9019e3 110 r = readData(invq, sizeof(invq)); if (r < 0) return;
andrewboyson 0:be515c9019e3 111
andrewboyson 21:a6d6e26dd742 112 /*
andrewboyson 0:be515c9019e3 113 Log("Primary key content\r\n");
andrewboyson 0:be515c9019e3 114 LogBytesAsHex( v, sizeof( v)); Log("\n\n");
andrewboyson 0:be515c9019e3 115 LogBytesAsHex( n, sizeof( n)); Log("\n\n");
andrewboyson 0:be515c9019e3 116 LogBytesAsHex( e, sizeof( e)); Log("\n\n");
andrewboyson 0:be515c9019e3 117 LogBytesAsHex( d, sizeof( d)); Log("\n\n");
andrewboyson 0:be515c9019e3 118 LogBytesAsHex( p, sizeof( p)); Log("\n\n");
andrewboyson 0:be515c9019e3 119 LogBytesAsHex( q, sizeof( q)); Log("\n\n");
andrewboyson 0:be515c9019e3 120 LogBytesAsHex( dp, sizeof( dp)); Log("\n\n");
andrewboyson 0:be515c9019e3 121 LogBytesAsHex( dq, sizeof( dq)); Log("\n\n");
andrewboyson 0:be515c9019e3 122 LogBytesAsHex(invq, sizeof(invq)); Log("\n\n");
andrewboyson 21:a6d6e26dd742 123 */
andrewboyson 0:be515c9019e3 124 }
andrewboyson 4:6a1d887f1cad 125 int PriKeyDecryptStart(uint8_t* message) //return the slot number for the decryption
andrewboyson 0:be515c9019e3 126 {
andrewboyson 1:9c66a551a67e 127 //Convert message to big number (little endian) format prior to decryption
andrewboyson 4:6a1d887f1cad 128 uint8_t leMessage[128];
andrewboyson 1:9c66a551a67e 129 for (int i = 0; i < 128; i++) leMessage[127 - i] = message[i];
andrewboyson 14:03a0b8fd6ddc 130 return RsaStart((uint32_t*)leMessage, (uint32_t*)p, (uint32_t*)q, (uint32_t*)dp, (uint32_t*)dq, (uint32_t*)invq);
andrewboyson 2:82268409e83f 131 }
andrewboyson 2:82268409e83f 132 bool PriKeyDecryptFinished(int slot)
andrewboyson 2:82268409e83f 133 {
andrewboyson 14:03a0b8fd6ddc 134 return RsaFinished(slot);
andrewboyson 0:be515c9019e3 135 }
andrewboyson 17:93feb2a51d58 136 uint8_t* PriKeyDecryptResultLittleEndian(int slot)
andrewboyson 0:be515c9019e3 137 {
andrewboyson 14:03a0b8fd6ddc 138 return (uint8_t*) RsaResult(slot);
andrewboyson 2:82268409e83f 139 }
andrewboyson 17:93feb2a51d58 140 void PriKeyDecryptResultTail(int slot, int length, uint8_t* pBuffer)
andrewboyson 17:93feb2a51d58 141 {
andrewboyson 17:93feb2a51d58 142 //Convert result from big number (little endian) format after decryption
andrewboyson 17:93feb2a51d58 143 uint8_t* pLittleEndian = (uint8_t*) RsaResult(slot);
andrewboyson 17:93feb2a51d58 144 for (int i = 0; i < length; i++) *(pBuffer + i) = *(pLittleEndian + length - 1 - i);
andrewboyson 17:93feb2a51d58 145 }
andrewboyson 2:82268409e83f 146 void PriKeyDecryptClear(int slot)
andrewboyson 2:82268409e83f 147 {
andrewboyson 14:03a0b8fd6ddc 148 RsaClear(slot);
andrewboyson 0:be515c9019e3 149 }