#include "myirc/sasl_mechanism.hpp" #include "myirc/openssl_utils.hpp" #include namespace myirc { auto SaslPlain::step(std::string_view msg) -> StepResult { if (complete_) { return Failure{}; } else { std::string reply; reply += authzid_; reply += '\0'; reply += authcid_; reply += '\0'; reply += password_; complete_ = true; return std::move(reply); } } auto SaslExternal::step(std::string_view msg) -> StepResult { if (complete_) { return Failure{}; } else { complete_ = true; return std::move(authzid_); } } auto SaslEcdsa::step(std::string_view msg) -> StepResult { switch (stage_) { case 0: stage_ = 1; return std::move(message1_); case 1: { stage_ = 2; Ref ctx {EVP_PKEY_CTX_new(key_.get(), nullptr)}; if (not ctx) { log_openssl_errors("ECDSA new context: "); return Failure{}; } if (0 >= EVP_PKEY_sign_init(ctx.get())) { log_openssl_errors("ECDSA init: "); return Failure{}; } const auto input = reinterpret_cast(msg.data()); size_t siglen; if (0 >= EVP_PKEY_sign(ctx.get(), nullptr, &siglen, input, msg.size())) { log_openssl_errors("ECDSA signature (presize): "); return Failure{}; } std::string result(siglen, '\0'); const auto output = reinterpret_cast(result.data()); if (0 >= EVP_PKEY_sign(ctx.get(), output, &siglen, input, msg.size())) { log_openssl_errors("ECDSA signature: "); return Failure{}; } result.resize(siglen); return std::move(result); } default: return Failure{}; } } } // namespace myirc