A simple library to support serving https.
Dependents: oldheating gps motorhome heating
pki/base64.c@0:be515c9019e3, 2019-07-25 (annotated)
- Committer:
- andrewboyson
- Date:
- Thu Jul 25 21:16:24 2019 +0000
- Revision:
- 0:be515c9019e3
Pulled together existing modules from https and big numbers into this one. Added TLS PRF module.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 0:be515c9019e3 | 1 | #include <stdbool.h> |
andrewboyson | 0:be515c9019e3 | 2 | #include <stdio.h> |
andrewboyson | 0:be515c9019e3 | 3 | #include "base64.h" |
andrewboyson | 0:be515c9019e3 | 4 | |
andrewboyson | 0:be515c9019e3 | 5 | char (*Base64ReadNextCharFunctionPointer)(void) = NULL; |
andrewboyson | 0:be515c9019e3 | 6 | |
andrewboyson | 0:be515c9019e3 | 7 | static int get6bits() |
andrewboyson | 0:be515c9019e3 | 8 | { |
andrewboyson | 0:be515c9019e3 | 9 | while (true) |
andrewboyson | 0:be515c9019e3 | 10 | { |
andrewboyson | 0:be515c9019e3 | 11 | char c = Base64ReadNextCharFunctionPointer(); |
andrewboyson | 0:be515c9019e3 | 12 | if (c == 0 ) return -1; //EOF or an error |
andrewboyson | 0:be515c9019e3 | 13 | else if (c == '-') return -1; //Finished |
andrewboyson | 0:be515c9019e3 | 14 | else if (c == '=') return -1; //Padding |
andrewboyson | 0:be515c9019e3 | 15 | else if (c == '/') return 63; |
andrewboyson | 0:be515c9019e3 | 16 | else if (c == '+') return 62; |
andrewboyson | 0:be515c9019e3 | 17 | else if (c >= 'a') return c - 'a' + 26; |
andrewboyson | 0:be515c9019e3 | 18 | else if (c >= 'A') return c - 'A' + 0; |
andrewboyson | 0:be515c9019e3 | 19 | else if (c >= '0') return c - '0' + 52; |
andrewboyson | 0:be515c9019e3 | 20 | else continue; |
andrewboyson | 0:be515c9019e3 | 21 | } |
andrewboyson | 0:be515c9019e3 | 22 | } |
andrewboyson | 0:be515c9019e3 | 23 | |
andrewboyson | 0:be515c9019e3 | 24 | static int last6 = 0; |
andrewboyson | 0:be515c9019e3 | 25 | static int posn = 0; |
andrewboyson | 0:be515c9019e3 | 26 | static bool finished = false; |
andrewboyson | 0:be515c9019e3 | 27 | int Base64ReadByte() |
andrewboyson | 0:be515c9019e3 | 28 | { |
andrewboyson | 0:be515c9019e3 | 29 | if (finished) return -1; |
andrewboyson | 0:be515c9019e3 | 30 | |
andrewboyson | 0:be515c9019e3 | 31 | /* |
andrewboyson | 0:be515c9019e3 | 32 | L = last |
andrewboyson | 0:be515c9019e3 | 33 | T = this |
andrewboyson | 0:be515c9019e3 | 34 | out |
andrewboyson | 0:be515c9019e3 | 35 | case 0 TTTTTTLL |
andrewboyson | 0:be515c9019e3 | 36 | case 1 LLLLTTTT |
andrewboyson | 0:be515c9019e3 | 37 | case 2 LLTTTTTT |
andrewboyson | 0:be515c9019e3 | 38 | */ |
andrewboyson | 0:be515c9019e3 | 39 | int this6 = 0; |
andrewboyson | 0:be515c9019e3 | 40 | int bits8 = 0; |
andrewboyson | 0:be515c9019e3 | 41 | |
andrewboyson | 0:be515c9019e3 | 42 | switch (posn) |
andrewboyson | 0:be515c9019e3 | 43 | { |
andrewboyson | 0:be515c9019e3 | 44 | case 0: //We have no bits leftover |
andrewboyson | 0:be515c9019e3 | 45 | { |
andrewboyson | 0:be515c9019e3 | 46 | this6 = get6bits(); if (this6 == -1) return -1; //EOF or an error |
andrewboyson | 0:be515c9019e3 | 47 | last6 = get6bits(); |
andrewboyson | 0:be515c9019e3 | 48 | if (last6 == -1) |
andrewboyson | 0:be515c9019e3 | 49 | { |
andrewboyson | 0:be515c9019e3 | 50 | last6 = 0; |
andrewboyson | 0:be515c9019e3 | 51 | finished = true; |
andrewboyson | 0:be515c9019e3 | 52 | } |
andrewboyson | 0:be515c9019e3 | 53 | bits8 = this6 << 2; |
andrewboyson | 0:be515c9019e3 | 54 | bits8 &= 0xFF; |
andrewboyson | 0:be515c9019e3 | 55 | bits8 |= last6 >> 4; |
andrewboyson | 0:be515c9019e3 | 56 | |
andrewboyson | 0:be515c9019e3 | 57 | posn = 1; |
andrewboyson | 0:be515c9019e3 | 58 | break; |
andrewboyson | 0:be515c9019e3 | 59 | } |
andrewboyson | 0:be515c9019e3 | 60 | case 1: //We have 4 bits leftover |
andrewboyson | 0:be515c9019e3 | 61 | { |
andrewboyson | 0:be515c9019e3 | 62 | this6 = get6bits(); if (this6 == -1) return -1; //EOF or an error |
andrewboyson | 0:be515c9019e3 | 63 | |
andrewboyson | 0:be515c9019e3 | 64 | bits8 = last6 << 4; |
andrewboyson | 0:be515c9019e3 | 65 | bits8 &= 0xFF; |
andrewboyson | 0:be515c9019e3 | 66 | bits8 |= this6 >> 2; |
andrewboyson | 0:be515c9019e3 | 67 | |
andrewboyson | 0:be515c9019e3 | 68 | last6 = this6; |
andrewboyson | 0:be515c9019e3 | 69 | |
andrewboyson | 0:be515c9019e3 | 70 | posn = 2; |
andrewboyson | 0:be515c9019e3 | 71 | break; |
andrewboyson | 0:be515c9019e3 | 72 | } |
andrewboyson | 0:be515c9019e3 | 73 | case 2: //We have 2 bits leftover |
andrewboyson | 0:be515c9019e3 | 74 | { |
andrewboyson | 0:be515c9019e3 | 75 | this6 = get6bits(); if (this6 == -1) return -1; //EOF or an error |
andrewboyson | 0:be515c9019e3 | 76 | |
andrewboyson | 0:be515c9019e3 | 77 | bits8 = last6 << 6; |
andrewboyson | 0:be515c9019e3 | 78 | bits8 &= 0xFF; |
andrewboyson | 0:be515c9019e3 | 79 | bits8 |= this6; |
andrewboyson | 0:be515c9019e3 | 80 | |
andrewboyson | 0:be515c9019e3 | 81 | posn = 0; |
andrewboyson | 0:be515c9019e3 | 82 | break; |
andrewboyson | 0:be515c9019e3 | 83 | } |
andrewboyson | 0:be515c9019e3 | 84 | } |
andrewboyson | 0:be515c9019e3 | 85 | |
andrewboyson | 0:be515c9019e3 | 86 | return bits8; |
andrewboyson | 0:be515c9019e3 | 87 | } |
andrewboyson | 0:be515c9019e3 | 88 | int Base64SkipLine() |
andrewboyson | 0:be515c9019e3 | 89 | { |
andrewboyson | 0:be515c9019e3 | 90 | last6 = 0; |
andrewboyson | 0:be515c9019e3 | 91 | posn = 0; |
andrewboyson | 0:be515c9019e3 | 92 | finished = false; |
andrewboyson | 0:be515c9019e3 | 93 | |
andrewboyson | 0:be515c9019e3 | 94 | while (true) |
andrewboyson | 0:be515c9019e3 | 95 | { |
andrewboyson | 0:be515c9019e3 | 96 | char c = Base64ReadNextCharFunctionPointer(); |
andrewboyson | 0:be515c9019e3 | 97 | if (c == 0 ) return -1; //EOF or an error |
andrewboyson | 0:be515c9019e3 | 98 | else if (c == '\n') return 0; //EOL |
andrewboyson | 0:be515c9019e3 | 99 | } |
andrewboyson | 0:be515c9019e3 | 100 | } |