| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,6 +2,7 @@ | |||
| 2 | 2 | #include <algorithm> | |
| 3 | 3 | #include <cstring> | |
| 4 | 4 | #include "openssl/bn.h" | |
| 5 | + #include "openssl/evp.h" | ||
| 5 | 6 | #if OPENSSL_VERSION_MAJOR >= 3 | |
| 6 | 7 | #include "openssl/provider.h" | |
| 7 | 8 | #endif | |
@@ -207,7 +208,7 @@ int NoPasswordCallback(char* buf, int size, int rwflag, void* u) { | |||
| 207 | 208 | } | |
| 208 | 209 | ||
| 209 | 210 | int PasswordCallback(char* buf, int size, int rwflag, void* u) { | |
| 210 | - const Buffer* passphrase = static_cast<const Buffer*>(u); | ||
| 211 | + auto passphrase = static_cast<const Buffer<char>*>(u); | ||
| 211 | 212 | if (passphrase != nullptr) { | |
| 212 | 213 | size_t buflen = static_cast<size_t>(size); | |
| 213 | 214 | size_t len = passphrase->len; | |
@@ -220,4 +221,72 @@ int PasswordCallback(char* buf, int size, int rwflag, void* u) { | |||
| 220 | 221 | return -1; | |
| 221 | 222 | } | |
| 222 | 223 | ||
| 224 | + // ============================================================================ | ||
| 225 | + // SPKAC | ||
| 226 | + | ||
| 227 | + bool VerifySpkac(const char* input, size_t length) { | ||
| 228 | + #ifdef OPENSSL_IS_BORINGSSL | ||
| 229 | + // OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters, | ||
| 230 | + // while BoringSSL uses EVP_DecodedLength and EVP_DecodeBase64, which do not. | ||
| 231 | + // As such, we trim those characters here for compatibility. | ||
| 232 | + // | ||
| 233 | + // find_last_not_of can return npos, which is the maximum value of size_t. | ||
| 234 | + // The + 1 will force a roll-ver to 0, which is the correct value. in that | ||
| 235 | + // case. | ||
| 236 | + length = std::string_view(input, length).find_last_not_of(" \n\r\t") + 1; | ||
| 237 | + #endif | ||
| 238 | + NetscapeSPKIPointer spki( | ||
| 239 | + NETSCAPE_SPKI_b64_decode(input, length)); | ||
| 240 | + if (!spki) | ||
| 241 | + return false; | ||
| 242 | + | ||
| 243 | + EVPKeyPointer pkey(X509_PUBKEY_get(spki->spkac->pubkey)); | ||
| 244 | + return pkey ? NETSCAPE_SPKI_verify(spki.get(), pkey.get()) > 0 : false; | ||
| 245 | + } | ||
| 246 | + | ||
| 247 | + BIOPointer ExportPublicKey(const char* input, size_t length) { | ||
| 248 | + BIOPointer bio(BIO_new(BIO_s_mem())); | ||
| 249 | + if (!bio) return {}; | ||
| 250 | + | ||
| 251 | + #ifdef OPENSSL_IS_BORINGSSL | ||
| 252 | + // OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters, | ||
| 253 | + // while BoringSSL uses EVP_DecodedLength and EVP_DecodeBase64, which do not. | ||
| 254 | + // As such, we trim those characters here for compatibility. | ||
| 255 | + length = std::string_view(input, length).find_last_not_of(" \n\r\t") + 1; | ||
| 256 | + #endif | ||
| 257 | + NetscapeSPKIPointer spki( | ||
| 258 | + NETSCAPE_SPKI_b64_decode(input, length)); | ||
| 259 | + if (!spki) return {}; | ||
| 260 | + | ||
| 261 | + EVPKeyPointer pkey(NETSCAPE_SPKI_get_pubkey(spki.get())); | ||
| 262 | + if (!pkey) return {}; | ||
| 263 | + | ||
| 264 | + if (PEM_write_bio_PUBKEY(bio.get(), pkey.get()) <= 0) return { }; | ||
| 265 | + | ||
| 266 | + return std::move(bio); | ||
| 267 | + } | ||
| 268 | + | ||
| 269 | + Buffer<char> ExportChallenge(const char* input, size_t length) { | ||
| 270 | + #ifdef OPENSSL_IS_BORINGSSL | ||
| 271 | + // OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters, | ||
| 272 | + // while BoringSSL uses EVP_DecodedLength and EVP_DecodeBase64, which do not. | ||
| 273 | + // As such, we trim those characters here for compatibility. | ||
| 274 | + length = std::string_view(input, length).find_last_not_of(" \n\r\t") + 1; | ||
| 275 | + #endif | ||
| 276 | + NetscapeSPKIPointer sp( | ||
| 277 | + NETSCAPE_SPKI_b64_decode(input, length)); | ||
| 278 | + if (!sp) return {}; | ||
| 279 | + | ||
| 280 | + unsigned char* buf = nullptr; | ||
| 281 | + int buf_size = ASN1_STRING_to_UTF8(&buf, sp->spkac->challenge); | ||
| 282 | + if (buf_size >= 0) { | ||
| 283 | + return { | ||
| 284 | + .data = reinterpret_cast<char*>(buf), | ||
| 285 | + .len = static_cast<size_t>(buf_size), | ||
| 286 | + }; | ||
| 287 | + } | ||
| 288 | + | ||
| 289 | + return {}; | ||
| 290 | + } | ||
| 291 | + | ||
| 223 | 292 | } // namespace ncrypto | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -269,9 +269,10 @@ bool testFipsEnabled(); | |||
| 269 | 269 | // ============================================================================ | |
| 270 | 270 | // Various utilities | |
| 271 | 271 | ||
| 272 | + template <typename T> | ||
| 272 | 273 | struct Buffer { | |
| 273 | - const void* data; | ||
| 274 | - size_t len; | ||
| 274 | + T* data = nullptr; | ||
| 275 | + size_t len = 0; | ||
| 275 | 276 | }; | |
| 276 | 277 | ||
| 277 | 278 | bool CSPRNG(void* buffer, size_t length) NCRYPTO_MUST_USE_RESULT; | |
@@ -285,6 +286,15 @@ int NoPasswordCallback(char* buf, int size, int rwflag, void* u); | |||
| 285 | 286 | ||
| 286 | 287 | int PasswordCallback(char* buf, int size, int rwflag, void* u); | |
| 287 | 288 | ||
| 289 | + // ============================================================================ | ||
| 290 | + // SPKAC | ||
| 291 | + | ||
| 292 | + bool VerifySpkac(const char* input, size_t length); | ||
| 293 | + BIOPointer ExportPublicKey(const char* input, size_t length); | ||
| 294 | + | ||
| 295 | + // The caller takes ownership of the returned Buffer<char> | ||
| 296 | + Buffer<char> ExportChallenge(const char* input, size_t length); | ||
| 297 | + | ||
| 288 | 298 | // ============================================================================ | |
| 289 | 299 | // Version metadata | |
| 290 | 300 | #define NCRYPTO_VERSION "0.0.1" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,6 +3,7 @@ | |||
| 3 | 3 | #include "crypto/crypto_util.h" | |
| 4 | 4 | #include "env-inl.h" | |
| 5 | 5 | #include "memory_tracker-inl.h" | |
| 6 | + #include "ncrypto.h" | ||
| 6 | 7 | #include "node.h" | |
| 7 | 8 | #include "v8.h" | |
| 8 | 9 | ||
@@ -16,25 +17,6 @@ using v8::Value; | |||
| 16 | 17 | ||
| 17 | 18 | namespace crypto { | |
| 18 | 19 | namespace SPKAC { | |
| 19 | - bool VerifySpkac(const ArrayBufferOrViewContents<char>& input) { | ||
| 20 | - size_t length = input.size(); | ||
| 21 | - #ifdef OPENSSL_IS_BORINGSSL | ||
| 22 | - // OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters, | ||
| 23 | - // while BoringSSL uses EVP_DecodedLength and EVP_DecodeBase64, which do not. | ||
| 24 | - // As such, we trim those characters here for compatibility. | ||
| 25 | - length = std::string(input.data()).find_last_not_of(" \n\r\t") + 1; | ||
| 26 | - #endif | ||
| 27 | - NetscapeSPKIPointer spki( | ||
| 28 | - NETSCAPE_SPKI_b64_decode(input.data(), length)); | ||
| 29 | - if (!spki) | ||
| 30 | - return false; | ||
| 31 | - | ||
| 32 | - EVPKeyPointer pkey(X509_PUBKEY_get(spki->spkac->pubkey)); | ||
| 33 | - if (!pkey) | ||
| 34 | - return false; | ||
| 35 | - | ||
| 36 | - return NETSCAPE_SPKI_verify(spki.get(), pkey.get()) > 0; | ||
| 37 | - } | ||
| 38 | 20 | ||
| 39 | 21 | void VerifySpkac(const FunctionCallbackInfo<Value>& args) { | |
| 40 | 22 | Environment* env = Environment::GetCurrent(args); | |
@@ -44,31 +26,7 @@ void VerifySpkac(const FunctionCallbackInfo<Value>& args) { | |||
| 44 | 26 | if (UNLIKELY(!input.CheckSizeInt32())) | |
| 45 | 27 | return THROW_ERR_OUT_OF_RANGE(env, "spkac is too large"); | |
| 46 | 28 | ||
| 47 | - args.GetReturnValue().Set(VerifySpkac(input)); | ||
| 48 | - } | ||
| 49 | - | ||
| 50 | - ByteSource ExportPublicKey(Environment* env, | ||
| 51 | - const ArrayBufferOrViewContents<char>& input) { | ||
| 52 | - BIOPointer bio(BIO_new(BIO_s_mem())); | ||
| 53 | - if (!bio) return ByteSource(); | ||
| 54 | - | ||
| 55 | - size_t length = input.size(); | ||
| 56 | - #ifdef OPENSSL_IS_BORINGSSL | ||
| 57 | - // OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters, | ||
| 58 | - // while BoringSSL uses EVP_DecodedLength and EVP_DecodeBase64, which do not. | ||
| 59 | - // As such, we trim those characters here for compatibility. | ||
| 60 | - length = std::string(input.data()).find_last_not_of(" \n\r\t") + 1; | ||
| 61 | - #endif | ||
| 62 | - NetscapeSPKIPointer spki( | ||
| 63 | - NETSCAPE_SPKI_b64_decode(input.data(), length)); | ||
| 64 | - if (!spki) return ByteSource(); | ||
| 65 | - | ||
| 66 | - EVPKeyPointer pkey(NETSCAPE_SPKI_get_pubkey(spki.get())); | ||
| 67 | - if (!pkey) return ByteSource(); | ||
| 68 | - | ||
| 69 | - if (PEM_write_bio_PUBKEY(bio.get(), pkey.get()) <= 0) return ByteSource(); | ||
| 70 | - | ||
| 71 | - return ByteSource::FromBIO(bio); | ||
| 29 | + args.GetReturnValue().Set(ncrypto::VerifySpkac(input.data(), input.size())); | ||
| 72 | 30 | } | |
| 73 | 31 | ||
| 74 | 32 | void ExportPublicKey(const FunctionCallbackInfo<Value>& args) { | |
@@ -80,30 +38,13 @@ void ExportPublicKey(const FunctionCallbackInfo<Value>& args) { | |||
| 80 | 38 | if (UNLIKELY(!input.CheckSizeInt32())) | |
| 81 | 39 | return THROW_ERR_OUT_OF_RANGE(env, "spkac is too large"); | |
| 82 | 40 | ||
| 83 | - ByteSource pkey = ExportPublicKey(env, input); | ||
| 84 | - if (!pkey) return args.GetReturnValue().SetEmptyString(); | ||
| 41 | + BIOPointer bio = ncrypto::ExportPublicKey(input.data(), input.size()); | ||
| 42 | + if (!bio) return args.GetReturnValue().SetEmptyString(); | ||
| 85 | 43 | ||
| 44 | + auto pkey = ByteSource::FromBIO(bio); | ||
| 86 | 45 | args.GetReturnValue().Set(pkey.ToBuffer(env).FromMaybe(Local<Value>())); | |
| 87 | 46 | } | |
| 88 | 47 | ||
| 89 | - ByteSource ExportChallenge(const ArrayBufferOrViewContents<char>& input) { | ||
| 90 | - size_t length = input.size(); | ||
| 91 | - #ifdef OPENSSL_IS_BORINGSSL | ||
| 92 | - // OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters, | ||
| 93 | - // while BoringSSL uses EVP_DecodedLength and EVP_DecodeBase64, which do not. | ||
| 94 | - // As such, we trim those characters here for compatibility. | ||
| 95 | - length = std::string(input.data()).find_last_not_of(" \n\r\t") + 1; | ||
| 96 | - #endif | ||
| 97 | - NetscapeSPKIPointer sp( | ||
| 98 | - NETSCAPE_SPKI_b64_decode(input.data(), length)); | ||
| 99 | - if (!sp) | ||
| 100 | - return ByteSource(); | ||
| 101 | - | ||
| 102 | - unsigned char* buf = nullptr; | ||
| 103 | - int buf_size = ASN1_STRING_to_UTF8(&buf, sp->spkac->challenge); | ||
| 104 | - return (buf_size >= 0) ? ByteSource::Allocated(buf, buf_size) : ByteSource(); | ||
| 105 | - } | ||
| 106 | - | ||
| 107 | 48 | void ExportChallenge(const FunctionCallbackInfo<Value>& args) { | |
| 108 | 49 | Environment* env = Environment::GetCurrent(args); | |
| 109 | 50 | ||
@@ -113,7 +54,8 @@ void ExportChallenge(const FunctionCallbackInfo<Value>& args) { | |||
| 113 | 54 | if (UNLIKELY(!input.CheckSizeInt32())) | |
| 114 | 55 | return THROW_ERR_OUT_OF_RANGE(env, "spkac is too large"); | |
| 115 | 56 | ||
| 116 | - ByteSource cert = ExportChallenge(input); | ||
| 57 | + auto cert = ByteSource::Allocated( | ||
| 58 | + ncrypto::ExportChallenge(input.data(), input.size())); | ||
| 117 | 59 | if (!cert) | |
| 118 | 60 | return args.GetReturnValue().SetEmptyString(); | |
| 119 | 61 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -275,6 +275,12 @@ class ByteSource { | |||
| 275 | 275 | v8::MaybeLocal<v8::Uint8Array> ToBuffer(Environment* env); | |
| 276 | 276 | ||
| 277 | 277 | static ByteSource Allocated(void* data, size_t size); | |
| 278 | + | ||
| 279 | + template <typename T> | ||
| 280 | + static ByteSource Allocated(const ncrypto::Buffer<T>& buffer) { | ||
| 281 | + return Allocated(buffer.data, buffer.len); | ||
| 282 | + } | ||
| 283 | + | ||
| 278 | 284 | static ByteSource Foreign(const void* data, size_t size); | |
| 279 | 285 | ||
| 280 | 286 | static ByteSource FromEncodedString(Environment* env, | |
| Back | FazBrowse Home | New Git URL |
0 commit comments