%PDF- %PDF-
| Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/crypto/ |
| Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/crypto/crypto_spkac.cc |
#include "crypto/crypto_spkac.h"
#include "crypto/crypto_common.h"
#include "crypto/crypto_util.h"
#include "env-inl.h"
#include "memory_tracker-inl.h"
#include "node.h"
#include "v8.h"
namespace node {
using v8::Context;
using v8::FunctionCallbackInfo;
using v8::Local;
using v8::Object;
using v8::Value;
namespace crypto {
namespace SPKAC {
bool VerifySpkac(const ArrayBufferOrViewContents<char>& input) {
size_t length = input.size();
#ifdef OPENSSL_IS_BORINGSSL
// OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters,
// while BoringSSL uses EVP_DecodedLength and EVP_DecodeBase64, which do not.
// As such, we trim those characters here for compatibility.
length = std::string(input.data()).find_last_not_of(" \n\r\t") + 1;
#endif
NetscapeSPKIPointer spki(
NETSCAPE_SPKI_b64_decode(input.data(), length));
if (!spki)
return false;
EVPKeyPointer pkey(X509_PUBKEY_get(spki->spkac->pubkey));
if (!pkey)
return false;
return NETSCAPE_SPKI_verify(spki.get(), pkey.get()) > 0;
}
void VerifySpkac(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
ArrayBufferOrViewContents<char> input(args[0]);
if (input.size() == 0)
return args.GetReturnValue().SetEmptyString();
if (UNLIKELY(!input.CheckSizeInt32()))
return THROW_ERR_OUT_OF_RANGE(env, "spkac is too large");
args.GetReturnValue().Set(VerifySpkac(input));
}
ByteSource ExportPublicKey(Environment* env,
const ArrayBufferOrViewContents<char>& input) {
BIOPointer bio(BIO_new(BIO_s_mem()));
if (!bio) return ByteSource();
size_t length = input.size();
#ifdef OPENSSL_IS_BORINGSSL
// OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters,
// while BoringSSL uses EVP_DecodedLength and EVP_DecodeBase64, which do not.
// As such, we trim those characters here for compatibility.
length = std::string(input.data()).find_last_not_of(" \n\r\t") + 1;
#endif
NetscapeSPKIPointer spki(
NETSCAPE_SPKI_b64_decode(input.data(), length));
if (!spki) return ByteSource();
EVPKeyPointer pkey(NETSCAPE_SPKI_get_pubkey(spki.get()));
if (!pkey) return ByteSource();
if (PEM_write_bio_PUBKEY(bio.get(), pkey.get()) <= 0) return ByteSource();
return ByteSource::FromBIO(bio);
}
void ExportPublicKey(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
ArrayBufferOrViewContents<char> input(args[0]);
if (input.size() == 0) return args.GetReturnValue().SetEmptyString();
if (UNLIKELY(!input.CheckSizeInt32()))
return THROW_ERR_OUT_OF_RANGE(env, "spkac is too large");
ByteSource pkey = ExportPublicKey(env, input);
if (!pkey) return args.GetReturnValue().SetEmptyString();
args.GetReturnValue().Set(pkey.ToBuffer(env).FromMaybe(Local<Value>()));
}
ByteSource ExportChallenge(const ArrayBufferOrViewContents<char>& input) {
size_t length = input.size();
#ifdef OPENSSL_IS_BORINGSSL
// OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters,
// while BoringSSL uses EVP_DecodedLength and EVP_DecodeBase64, which do not.
// As such, we trim those characters here for compatibility.
length = std::string(input.data()).find_last_not_of(" \n\r\t") + 1;
#endif
NetscapeSPKIPointer sp(
NETSCAPE_SPKI_b64_decode(input.data(), length));
if (!sp)
return ByteSource();
unsigned char* buf = nullptr;
int buf_size = ASN1_STRING_to_UTF8(&buf, sp->spkac->challenge);
return (buf_size >= 0) ? ByteSource::Allocated(buf, buf_size) : ByteSource();
}
void ExportChallenge(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
ArrayBufferOrViewContents<char> input(args[0]);
if (input.size() == 0)
return args.GetReturnValue().SetEmptyString();
if (UNLIKELY(!input.CheckSizeInt32()))
return THROW_ERR_OUT_OF_RANGE(env, "spkac is too large");
ByteSource cert = ExportChallenge(input);
if (!cert)
return args.GetReturnValue().SetEmptyString();
Local<Value> outString =
Encode(env->isolate(), cert.data<char>(), cert.size(), BUFFER);
args.GetReturnValue().Set(outString);
}
void Initialize(Environment* env, Local<Object> target) {
Local<Context> context = env->context();
SetMethodNoSideEffect(context, target, "certVerifySpkac", VerifySpkac);
SetMethodNoSideEffect(
context, target, "certExportPublicKey", ExportPublicKey);
SetMethodNoSideEffect(
context, target, "certExportChallenge", ExportChallenge);
}
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(VerifySpkac);
registry->Register(ExportPublicKey);
registry->Register(ExportChallenge);
}
} // namespace SPKAC
} // namespace crypto
} // namespace node