-
Notifications
You must be signed in to change notification settings - Fork 4
/
YubiOTP.cpp
126 lines (107 loc) · 3.36 KB
/
YubiOTP.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
YubiOTP.cpp - Library for validating Yubi One-Time-Passwords (OTP)
Created by Cyber Ninjas Inc, March 4, 2016
Released under GPL v3
*/
#include "Arduino.h"
#include "YubiOTP.h"
#include "Client.h"
#include "OTPResponse.h"
#include "Sha1.h"
#include "libb64\cdecode.h"
#include "libb64\cencode.h"
YubiOTP::YubiOTP(Client& client) : _client(client){
_servers[0] = "api.yubico.com";
_servers[1] = "api2.yubico.com";
_servers[2] = "api3.yubico.com";
_servers[3] = "api4.yubico.com";
_servers[4] = "api5.yubico.com";
_id = 1;
_port = 80;
_shouldSign=true;
_maxTimeMilliSecs=3000;
}
void YubiOTP::setb64HmacKey(String key){
_b64hmackey = key;
}
void YubiOTP::setOTP(String otp){
_otp = otp;
}
void YubiOTP::setId(int id){
_id = id;
}
void YubiOTP::setSigned(boolean shouldSign){
_shouldSign = shouldSign;
}
void YubiOTP::setServers(String servers[], int serverCount){
Serial.println("Not Implemented");
}
boolean YubiOTP::validateOTP(){
this->getOTPResult();
}
String YubiOTP::getNonce(){
String nonce = "asdlkjasdfweWErewrsdfsdfs";
return nonce;
}
String YubiOTP::getOTPResult(){
String url = "/wsapi/2.0/verify?";
String params = "id=" + String(_id) + "&otp=" + _otp + "&nonce=" + this->getNonce() + "×tamp=1";
if(_shouldSign){
String h = this->getHMACSha1(params);
url += "&h=" + h;
}
for(const String &server : _servers) {
String response = this->getRequest(server, _port, url + params);
if(response.length() != 0){
Serial.println(url);
Serial.println(response);
OTPResponse resp(response);
}
}
return "Hi";
}
String YubiOTP::getHMACSha1(String input){
//Convert String _hmackey to char[] hmackey
String hmackey = this->base64DecodeString(_b64hmackey);
int hmacKeySize = hmackey.length() + 1;
char cHmacKey[hmackeySize];
hmackey.toCharArray(cHmacKey, hmacKeySize);
Sha1.initHmac((uint8_t *)cHmacKey,hmacKeySize);
Sha1.print(input);
String hash = String(Sha1.resultHmac());
return base64EncodeString(hash);
}
String YubiOTP::base64DecodeString(String input) {
int inputSize = input.length() + 1;
char cInput[inputSize];
input.toCharArray(cInput, inputSize);
int outputSize = base64_decode_expected_len(inputSize);
char cOutput[outputSize];
base64_decode_chars(cInput, inputSize, cOutput);
return String(cOutput);
}
String YubiOTP::base64EncodeString(String input) {
int inputSize = input.length() + 1;
char cInput[inputSize];
input.toCharArray(cInput, inputSize);
int outputSize = base64_encode_expected_len(inputSize);
char cOutput[outputSize];
base64_encode_chars(cInput, inputSize, cOutput);
return String(cOutput);
}
String YubiOTP::getRequest(String server, int port, String url){
String response = "";
char cServer[server.length() + 1];
server.toCharArray(cServer, server.length() + 1);
if(_client.connect(cServer, port)){
_client.println("GET " + url + " HTTP/1.1");
_client.println("Host: " + server);
_client.println();
delay(5000);
while (_client.available()) {
char c = _client.read();
response = response + c;
}
}
return response;
}