A simple library to support serving https.
Dependents: oldheating gps motorhome heating
pki/base64.c@24:cb43290fc439, 2020-04-01 (annotated)
- Committer:
- andrewboyson
- Date:
- Wed Apr 01 12:48:52 2020 +0000
- Revision:
- 24:cb43290fc439
- Parent:
- 0:be515c9019e3
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?
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 | } |