A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Fri Jul 26 13:49:52 2019 +0000
Revision:
1:9c66a551a67e
Parent:
0:be515c9019e3
Child:
2:82268409e83f
Moved TLS module from net library to crypto library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 0:be515c9019e3 1 #include "base64.h"
andrewboyson 0:be515c9019e3 2 #include "log.h"
andrewboyson 0:be515c9019e3 3 #include "bignum.h"
andrewboyson 0:be515c9019e3 4
andrewboyson 0:be515c9019e3 5 /*
andrewboyson 0:be515c9019e3 6 RSAPrivateKey ::= SEQUENCE {
andrewboyson 0:be515c9019e3 7 version INTEGER,
andrewboyson 0:be515c9019e3 8 modulus INTEGER, -- n
andrewboyson 0:be515c9019e3 9 publicExponent INTEGER, -- e
andrewboyson 0:be515c9019e3 10 privateExponent INTEGER, -- d
andrewboyson 0:be515c9019e3 11 prime1 INTEGER, -- p
andrewboyson 0:be515c9019e3 12 prime2 INTEGER, -- q
andrewboyson 0:be515c9019e3 13 exponent1 INTEGER, -- d mod (p-1)
andrewboyson 0:be515c9019e3 14 exponent2 INTEGER, -- d mod (q-1)
andrewboyson 0:be515c9019e3 15 coefficient INTEGER, -- (inverse of q) mod p
andrewboyson 0:be515c9019e3 16 otherPrimeInfos OtherPrimeInfos OPTIONAL
andrewboyson 0:be515c9019e3 17 */
andrewboyson 0:be515c9019e3 18
andrewboyson 0:be515c9019e3 19 char v [ 4]; //version
andrewboyson 0:be515c9019e3 20 char n [128]; //modulus
andrewboyson 0:be515c9019e3 21 char e [ 4]; //publicExponent
andrewboyson 0:be515c9019e3 22 char d [128]; //privateExponent
andrewboyson 0:be515c9019e3 23 char p [ 64]; //prime1
andrewboyson 0:be515c9019e3 24 char q [ 64]; //prime2
andrewboyson 0:be515c9019e3 25 char dp [ 64]; //exponent1 -- d mod (p-1)
andrewboyson 0:be515c9019e3 26 char dq [ 64]; //exponent2 -- d mod (q-1)
andrewboyson 0:be515c9019e3 27 char invq[ 64]; //coefficient -- (inverse of q) mod p
andrewboyson 0:be515c9019e3 28
andrewboyson 0:be515c9019e3 29 static const char* pNext;
andrewboyson 0:be515c9019e3 30 static const char* buffer =
andrewboyson 0:be515c9019e3 31 #include "pri-key.inc"
andrewboyson 0:be515c9019e3 32 ;
andrewboyson 0:be515c9019e3 33 static char readChar()
andrewboyson 0:be515c9019e3 34 {
andrewboyson 0:be515c9019e3 35 char c = *pNext;
andrewboyson 0:be515c9019e3 36 if (!c) return 0;
andrewboyson 0:be515c9019e3 37 pNext++;
andrewboyson 0:be515c9019e3 38 return c;
andrewboyson 0:be515c9019e3 39 }
andrewboyson 0:be515c9019e3 40 static int readLength()
andrewboyson 0:be515c9019e3 41 {
andrewboyson 0:be515c9019e3 42 int c = Base64ReadByte();
andrewboyson 0:be515c9019e3 43 if (c == -1) return -1; //EOF or an error
andrewboyson 0:be515c9019e3 44 if (c < 0x80) return c; //Single byte length
andrewboyson 0:be515c9019e3 45 if (c == 0x80) return -1; //indefinite form - do not use
andrewboyson 0:be515c9019e3 46 int numberOfBytes = c - 0x80;
andrewboyson 0:be515c9019e3 47 int len = 0;
andrewboyson 0:be515c9019e3 48 for (int i = 0; i < numberOfBytes; i++)
andrewboyson 0:be515c9019e3 49 {
andrewboyson 0:be515c9019e3 50 len <<= 8;
andrewboyson 0:be515c9019e3 51 c = Base64ReadByte();
andrewboyson 0:be515c9019e3 52 if (c == -1) return -1; //EOF or an error
andrewboyson 0:be515c9019e3 53 len |= c;
andrewboyson 0:be515c9019e3 54 }
andrewboyson 0:be515c9019e3 55 return len;
andrewboyson 0:be515c9019e3 56 }
andrewboyson 0:be515c9019e3 57 static int readSequence()
andrewboyson 0:be515c9019e3 58 {
andrewboyson 0:be515c9019e3 59 int c = Base64ReadByte();
andrewboyson 0:be515c9019e3 60 if (c == -1) return -1; //EOF or an error
andrewboyson 0:be515c9019e3 61 if (c != 0x30) return -1; //Not SEQUENCE type
andrewboyson 0:be515c9019e3 62 int len = readLength();
andrewboyson 0:be515c9019e3 63 return len;
andrewboyson 0:be515c9019e3 64 }
andrewboyson 0:be515c9019e3 65 static int readData(char* data, int size) //Reads the data from big-endian 'pem' format into little-endian 'bn' format
andrewboyson 0:be515c9019e3 66 {
andrewboyson 0:be515c9019e3 67 int c = Base64ReadByte();
andrewboyson 0:be515c9019e3 68 if (c == -1) return -1; //EOF or an error
andrewboyson 0:be515c9019e3 69 if (c != 0x02) return -1; //Not INTEGER type
andrewboyson 0:be515c9019e3 70 int pemLength = readLength();
andrewboyson 0:be515c9019e3 71 if (pemLength == -1) return -1; //EOF or an error
andrewboyson 0:be515c9019e3 72
andrewboyson 0:be515c9019e3 73 int finalLength = pemLength;
andrewboyson 0:be515c9019e3 74 for (int i = 0; i < pemLength; i++)
andrewboyson 0:be515c9019e3 75 {
andrewboyson 0:be515c9019e3 76 c = Base64ReadByte();
andrewboyson 0:be515c9019e3 77 if (c == -1) return -1; //EOF or an error
andrewboyson 0:be515c9019e3 78 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 79 {
andrewboyson 0:be515c9019e3 80 finalLength--;
andrewboyson 0:be515c9019e3 81 }
andrewboyson 0:be515c9019e3 82 else
andrewboyson 0:be515c9019e3 83 {
andrewboyson 0:be515c9019e3 84 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 85 }
andrewboyson 0:be515c9019e3 86 }
andrewboyson 0:be515c9019e3 87 for (int i = finalLength; i < size; i++) data[i] = 0;
andrewboyson 0:be515c9019e3 88
andrewboyson 0:be515c9019e3 89 return finalLength + 1;
andrewboyson 0:be515c9019e3 90 }
andrewboyson 0:be515c9019e3 91 void PriKeyInit()
andrewboyson 0:be515c9019e3 92 {
andrewboyson 0:be515c9019e3 93 pNext = buffer;
andrewboyson 0:be515c9019e3 94 Base64ReadNextCharFunctionPointer = readChar;
andrewboyson 0:be515c9019e3 95
andrewboyson 0:be515c9019e3 96 int r = 0;
andrewboyson 0:be515c9019e3 97 r = Base64SkipLine(); if (r < 0) return;
andrewboyson 0:be515c9019e3 98 r = readSequence(); if (r < 0) return;
andrewboyson 0:be515c9019e3 99
andrewboyson 0:be515c9019e3 100 r = readData( v, sizeof( v)); if (r < 0) return;
andrewboyson 0:be515c9019e3 101 r = readData( n, sizeof( n)); if (r < 0) return;
andrewboyson 0:be515c9019e3 102 r = readData( e, sizeof( e)); if (r < 0) return;
andrewboyson 0:be515c9019e3 103 r = readData( d, sizeof( d)); if (r < 0) return;
andrewboyson 0:be515c9019e3 104 r = readData( p, sizeof( p)); if (r < 0) return;
andrewboyson 0:be515c9019e3 105 r = readData( q, sizeof( q)); if (r < 0) return;
andrewboyson 0:be515c9019e3 106 r = readData( dp, sizeof( dp)); if (r < 0) return;
andrewboyson 0:be515c9019e3 107 r = readData( dq, sizeof( dq)); if (r < 0) return;
andrewboyson 0:be515c9019e3 108 r = readData(invq, sizeof(invq)); if (r < 0) return;
andrewboyson 0:be515c9019e3 109
andrewboyson 0:be515c9019e3 110 Log("Primary key content\r\n");
andrewboyson 0:be515c9019e3 111 LogBytesAsHex( v, sizeof( v)); Log("\n\n");
andrewboyson 0:be515c9019e3 112 LogBytesAsHex( n, sizeof( n)); Log("\n\n");
andrewboyson 0:be515c9019e3 113 LogBytesAsHex( e, sizeof( e)); Log("\n\n");
andrewboyson 0:be515c9019e3 114 LogBytesAsHex( d, sizeof( d)); Log("\n\n");
andrewboyson 0:be515c9019e3 115 LogBytesAsHex( p, sizeof( p)); Log("\n\n");
andrewboyson 0:be515c9019e3 116 LogBytesAsHex( q, sizeof( q)); Log("\n\n");
andrewboyson 0:be515c9019e3 117 LogBytesAsHex( dp, sizeof( dp)); Log("\n\n");
andrewboyson 0:be515c9019e3 118 LogBytesAsHex( dq, sizeof( dq)); Log("\n\n");
andrewboyson 0:be515c9019e3 119 LogBytesAsHex(invq, sizeof(invq)); Log("\n\n");
andrewboyson 0:be515c9019e3 120 }
andrewboyson 0:be515c9019e3 121 void PriKeyDecryptStart(char* message, char* result)
andrewboyson 0:be515c9019e3 122 {
andrewboyson 1:9c66a551a67e 123 //Convert message to big number (little endian) format prior to decryption
andrewboyson 1:9c66a551a67e 124 char leMessage[128];
andrewboyson 1:9c66a551a67e 125 for (int i = 0; i < 128; i++) leMessage[127 - i] = message[i];
andrewboyson 1:9c66a551a67e 126 BnExpModStart((uint32_t*)leMessage, (uint32_t*)d, (uint32_t*)n, (uint32_t*)result);
andrewboyson 0:be515c9019e3 127 }
andrewboyson 0:be515c9019e3 128 bool PriKeyDecryptFinished()
andrewboyson 0:be515c9019e3 129 {
andrewboyson 0:be515c9019e3 130 return BnExpModStatus == BIGNUM_CALC_FINISHED;
andrewboyson 0:be515c9019e3 131 }