blob: df1ff26eb4790e7954f64af75a87ba2c09e1993c [file] [log] [blame]
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "hermes/smdp_impl.h"
#include <utility>
#include <base/base64.h>
#include <base/bind.h>
#include <base/json/json_reader.h>
#include <base/json/json_writer.h>
#include <base/values.h>
namespace hermes {
SmdpImpl::SmdpImpl(const std::string& server_hostname)
: server_hostname_(server_hostname),
server_transport_(brillo::http::Transport::CreateDefault()),
weak_factory_(this) {}
void SmdpImpl::InitiateAuthentication(
const std::vector<uint8_t>& info1,
const std::vector<uint8_t>& challenge,
const InitiateAuthenticationCallback& data_callback,
const ErrorCallback& error_callback) {
std::string encoded_info1(info1.begin(), info1.end());
base::Base64Encode(encoded_info1, &encoded_info1);
std::string encoded_challenge(challenge.begin(), challenge.end());
base::Base64Encode(encoded_challenge, &encoded_challenge);
base::DictionaryValue http_params;
http_params.SetString("euiccInfo1", encoded_info1);
http_params.SetString("euiccChallenge", encoded_challenge);
http_params.SetString("smdpAddress", server_hostname_);
std::string http_body;
base::JSONWriter::Write(http_params, &http_body);
SendJsonRequest(
"https://" + server_hostname_ +
"/gsma/rsp2/es9plus/initiateAuthentication",
http_body,
base::Bind(&SmdpImpl::OnInitiateAuthenticationResponse,
weak_factory_.GetWeakPtr(), data_callback, error_callback),
error_callback);
}
void SmdpImpl::OnHttpResponse(
const base::Callback<void(DictionaryPtr)>& data_callback,
const ErrorCallback& error_callback,
brillo::http::RequestID request_id,
std::unique_ptr<brillo::http::Response> response) {
if (!response) {
error_callback.Run(std::vector<uint8_t>());
return;
}
std::string raw_data = response->ExtractDataAsString();
std::unique_ptr<base::Value> result = base::JSONReader::Read(raw_data);
if (result) {
data_callback.Run(base::DictionaryValue::From(std::move(result)));
} else {
error_callback.Run(std::vector<uint8_t>());
return;
}
}
void SmdpImpl::OnInitiateAuthenticationResponse(
const InitiateAuthenticationCallback& data_callback,
const ErrorCallback& error_callback,
std::unique_ptr<base::DictionaryValue> json_dict) {
std::string encoded_buffer;
std::string server_signed1;
if (!json_dict->GetString("serverSigned1", &encoded_buffer)) {
error_callback.Run(std::vector<uint8_t>());
return;
}
base::Base64Decode(encoded_buffer, &server_signed1);
std::string server_signature1;
if (!json_dict->GetString("serverSignature1", &encoded_buffer)) {
error_callback.Run(std::vector<uint8_t>());
return;
}
base::Base64Decode(encoded_buffer, &server_signature1);
std::string public_keys_to_use;
if (!json_dict->GetString("euiccCiPKIdToBeUsed", &encoded_buffer)) {
error_callback.Run(std::vector<uint8_t>());
return;
}
base::Base64Decode(encoded_buffer, &public_keys_to_use);
std::string server_certificate;
if (!json_dict->GetString("serverCertificate", &encoded_buffer)) {
error_callback.Run(std::vector<uint8_t>());
return;
}
base::Base64Decode(encoded_buffer, &server_certificate);
data_callback.Run(
std::vector<uint8_t>(server_signed1.begin(), server_signed1.end()),
std::vector<uint8_t>(server_signature1.begin(), server_signature1.end()),
std::vector<uint8_t>(public_keys_to_use.begin(),
public_keys_to_use.end()),
std::vector<uint8_t>(server_certificate.begin(),
server_certificate.end()));
}
void SmdpImpl::OnInitiateAuthenticationError(
const ErrorCallback& error_callback,
brillo::http::RequestID request_id,
const brillo::Error* error) {}
void SmdpImpl::SendJsonRequest(
const std::string& url,
const std::string& json_data,
const base::Callback<void(DictionaryPtr)>& data_callback,
const ErrorCallback& error_callback) {
brillo::ErrorPtr error = nullptr;
brillo::http::Request request(url, brillo::http::request_type::kPost,
server_transport_);
request.SetContentType("application/json");
request.SetUserAgent("gsma-rsp-lpad");
request.AddHeader("X-Admin-Protocol", "gsma/rsp/v2.0.0");
request.AddRequestBody(json_data.data(), json_data.size(), &error);
CHECK(!error);
request.GetResponse(
base::Bind(&SmdpImpl::OnHttpResponse, weak_factory_.GetWeakPtr(),
data_callback, error_callback),
base::Bind(&SmdpImpl::OnInitiateAuthenticationError,
weak_factory_.GetWeakPtr(), error_callback));
}
// TODO(jruthe): update data_callback to the correct base::Callback signature
void SmdpImpl::AuthenticateClient(const std::vector<uint8_t>& data,
const base::Closure& data_callback,
const ErrorCallback& error_callback) const {}
} // namespace hermes