11cb0ef41Sopenharmony_ci#include "base_object-inl.h" 21cb0ef41Sopenharmony_ci#include "crypto_x509.h" 31cb0ef41Sopenharmony_ci#include "crypto_common.h" 41cb0ef41Sopenharmony_ci#include "crypto_context.h" 51cb0ef41Sopenharmony_ci#include "crypto_keys.h" 61cb0ef41Sopenharmony_ci#include "crypto_bio.h" 71cb0ef41Sopenharmony_ci#include "env-inl.h" 81cb0ef41Sopenharmony_ci#include "memory_tracker-inl.h" 91cb0ef41Sopenharmony_ci#include "node_errors.h" 101cb0ef41Sopenharmony_ci#include "util-inl.h" 111cb0ef41Sopenharmony_ci#include "v8.h" 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci#include <string> 141cb0ef41Sopenharmony_ci#include <vector> 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_cinamespace node { 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ciusing v8::ArrayBufferView; 191cb0ef41Sopenharmony_ciusing v8::Context; 201cb0ef41Sopenharmony_ciusing v8::EscapableHandleScope; 211cb0ef41Sopenharmony_ciusing v8::Function; 221cb0ef41Sopenharmony_ciusing v8::FunctionCallbackInfo; 231cb0ef41Sopenharmony_ciusing v8::FunctionTemplate; 241cb0ef41Sopenharmony_ciusing v8::Isolate; 251cb0ef41Sopenharmony_ciusing v8::Local; 261cb0ef41Sopenharmony_ciusing v8::MaybeLocal; 271cb0ef41Sopenharmony_ciusing v8::Object; 281cb0ef41Sopenharmony_ciusing v8::Uint32; 291cb0ef41Sopenharmony_ciusing v8::Value; 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_cinamespace crypto { 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ciManagedX509::ManagedX509(X509Pointer&& cert) : cert_(std::move(cert)) {} 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ciManagedX509::ManagedX509(const ManagedX509& that) { 361cb0ef41Sopenharmony_ci *this = that; 371cb0ef41Sopenharmony_ci} 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ciManagedX509& ManagedX509::operator=(const ManagedX509& that) { 401cb0ef41Sopenharmony_ci cert_.reset(that.get()); 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci if (cert_) 431cb0ef41Sopenharmony_ci X509_up_ref(cert_.get()); 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci return *this; 461cb0ef41Sopenharmony_ci} 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_civoid ManagedX509::MemoryInfo(MemoryTracker* tracker) const { 491cb0ef41Sopenharmony_ci // This is an approximation based on the der encoding size. 501cb0ef41Sopenharmony_ci int size = i2d_X509(cert_.get(), nullptr); 511cb0ef41Sopenharmony_ci tracker->TrackFieldWithSize("cert", size); 521cb0ef41Sopenharmony_ci} 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_cinamespace { 551cb0ef41Sopenharmony_citemplate <const EVP_MD* (*algo)()> 561cb0ef41Sopenharmony_civoid Fingerprint(const FunctionCallbackInfo<Value>& args) { 571cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 581cb0ef41Sopenharmony_ci X509Certificate* cert; 591cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); 601cb0ef41Sopenharmony_ci Local<Value> ret; 611cb0ef41Sopenharmony_ci if (GetFingerprintDigest(env, algo(), cert->get()).ToLocal(&ret)) 621cb0ef41Sopenharmony_ci args.GetReturnValue().Set(ret); 631cb0ef41Sopenharmony_ci} 641cb0ef41Sopenharmony_ci} // namespace 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ciLocal<FunctionTemplate> X509Certificate::GetConstructorTemplate( 671cb0ef41Sopenharmony_ci Environment* env) { 681cb0ef41Sopenharmony_ci Local<FunctionTemplate> tmpl = env->x509_constructor_template(); 691cb0ef41Sopenharmony_ci if (tmpl.IsEmpty()) { 701cb0ef41Sopenharmony_ci Isolate* isolate = env->isolate(); 711cb0ef41Sopenharmony_ci tmpl = NewFunctionTemplate(isolate, nullptr); 721cb0ef41Sopenharmony_ci tmpl->InstanceTemplate()->SetInternalFieldCount( 731cb0ef41Sopenharmony_ci BaseObject::kInternalFieldCount); 741cb0ef41Sopenharmony_ci tmpl->Inherit(BaseObject::GetConstructorTemplate(env)); 751cb0ef41Sopenharmony_ci tmpl->SetClassName( 761cb0ef41Sopenharmony_ci FIXED_ONE_BYTE_STRING(env->isolate(), "X509Certificate")); 771cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "subject", Subject); 781cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "subjectAltName", SubjectAltName); 791cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "infoAccess", InfoAccess); 801cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "issuer", Issuer); 811cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "validTo", ValidTo); 821cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "validFrom", ValidFrom); 831cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "fingerprint", Fingerprint<EVP_sha1>); 841cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "fingerprint256", Fingerprint<EVP_sha256>); 851cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "fingerprint512", Fingerprint<EVP_sha512>); 861cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "keyUsage", KeyUsage); 871cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "serialNumber", SerialNumber); 881cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "pem", Pem); 891cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "raw", Raw); 901cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "publicKey", PublicKey); 911cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "checkCA", CheckCA); 921cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "checkHost", CheckHost); 931cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "checkEmail", CheckEmail); 941cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "checkIP", CheckIP); 951cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "checkIssued", CheckIssued); 961cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "checkPrivateKey", CheckPrivateKey); 971cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "verify", Verify); 981cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "toLegacy", ToLegacy); 991cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "getIssuerCert", GetIssuerCert); 1001cb0ef41Sopenharmony_ci env->set_x509_constructor_template(tmpl); 1011cb0ef41Sopenharmony_ci } 1021cb0ef41Sopenharmony_ci return tmpl; 1031cb0ef41Sopenharmony_ci} 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_cibool X509Certificate::HasInstance(Environment* env, Local<Object> object) { 1061cb0ef41Sopenharmony_ci return GetConstructorTemplate(env)->HasInstance(object); 1071cb0ef41Sopenharmony_ci} 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ciMaybeLocal<Object> X509Certificate::New( 1101cb0ef41Sopenharmony_ci Environment* env, 1111cb0ef41Sopenharmony_ci X509Pointer cert, 1121cb0ef41Sopenharmony_ci STACK_OF(X509)* issuer_chain) { 1131cb0ef41Sopenharmony_ci std::shared_ptr<ManagedX509> mcert(new ManagedX509(std::move(cert))); 1141cb0ef41Sopenharmony_ci return New(env, std::move(mcert), issuer_chain); 1151cb0ef41Sopenharmony_ci} 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ciMaybeLocal<Object> X509Certificate::New( 1181cb0ef41Sopenharmony_ci Environment* env, 1191cb0ef41Sopenharmony_ci std::shared_ptr<ManagedX509> cert, 1201cb0ef41Sopenharmony_ci STACK_OF(X509)* issuer_chain) { 1211cb0ef41Sopenharmony_ci EscapableHandleScope scope(env->isolate()); 1221cb0ef41Sopenharmony_ci Local<Function> ctor; 1231cb0ef41Sopenharmony_ci if (!GetConstructorTemplate(env)->GetFunction(env->context()).ToLocal(&ctor)) 1241cb0ef41Sopenharmony_ci return MaybeLocal<Object>(); 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci Local<Object> obj; 1271cb0ef41Sopenharmony_ci if (!ctor->NewInstance(env->context()).ToLocal(&obj)) 1281cb0ef41Sopenharmony_ci return MaybeLocal<Object>(); 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci new X509Certificate(env, obj, std::move(cert), issuer_chain); 1311cb0ef41Sopenharmony_ci return scope.Escape(obj); 1321cb0ef41Sopenharmony_ci} 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ciMaybeLocal<Object> X509Certificate::GetCert( 1351cb0ef41Sopenharmony_ci Environment* env, 1361cb0ef41Sopenharmony_ci const SSLPointer& ssl) { 1371cb0ef41Sopenharmony_ci ClearErrorOnReturn clear_error_on_return; 1381cb0ef41Sopenharmony_ci X509* cert = SSL_get_certificate(ssl.get()); 1391cb0ef41Sopenharmony_ci if (cert == nullptr) 1401cb0ef41Sopenharmony_ci return MaybeLocal<Object>(); 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ci X509Pointer ptr(X509_dup(cert)); 1431cb0ef41Sopenharmony_ci return New(env, std::move(ptr)); 1441cb0ef41Sopenharmony_ci} 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ciMaybeLocal<Object> X509Certificate::GetPeerCert( 1471cb0ef41Sopenharmony_ci Environment* env, 1481cb0ef41Sopenharmony_ci const SSLPointer& ssl, 1491cb0ef41Sopenharmony_ci GetPeerCertificateFlag flag) { 1501cb0ef41Sopenharmony_ci ClearErrorOnReturn clear_error_on_return; 1511cb0ef41Sopenharmony_ci MaybeLocal<Object> maybe_cert; 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci bool is_server = 1541cb0ef41Sopenharmony_ci static_cast<int>(flag) & static_cast<int>(GetPeerCertificateFlag::SERVER); 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_ci X509Pointer cert(is_server ? SSL_get_peer_certificate(ssl.get()) : nullptr); 1571cb0ef41Sopenharmony_ci STACK_OF(X509)* ssl_certs = SSL_get_peer_cert_chain(ssl.get()); 1581cb0ef41Sopenharmony_ci if (!cert && (ssl_certs == nullptr || sk_X509_num(ssl_certs) == 0)) 1591cb0ef41Sopenharmony_ci return MaybeLocal<Object>(); 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_ci std::vector<Local<Value>> certs; 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci if (!cert) { 1641cb0ef41Sopenharmony_ci cert.reset(sk_X509_value(ssl_certs, 0)); 1651cb0ef41Sopenharmony_ci sk_X509_delete(ssl_certs, 0); 1661cb0ef41Sopenharmony_ci } 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ci return sk_X509_num(ssl_certs) 1691cb0ef41Sopenharmony_ci ? New(env, std::move(cert), ssl_certs) 1701cb0ef41Sopenharmony_ci : New(env, std::move(cert)); 1711cb0ef41Sopenharmony_ci} 1721cb0ef41Sopenharmony_ci 1731cb0ef41Sopenharmony_civoid X509Certificate::Parse(const FunctionCallbackInfo<Value>& args) { 1741cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ci CHECK(args[0]->IsArrayBufferView()); 1771cb0ef41Sopenharmony_ci ArrayBufferViewContents<unsigned char> buf(args[0].As<ArrayBufferView>()); 1781cb0ef41Sopenharmony_ci const unsigned char* data = buf.data(); 1791cb0ef41Sopenharmony_ci unsigned data_len = buf.length(); 1801cb0ef41Sopenharmony_ci 1811cb0ef41Sopenharmony_ci ClearErrorOnReturn clear_error_on_return; 1821cb0ef41Sopenharmony_ci BIOPointer bio(LoadBIO(env, args[0])); 1831cb0ef41Sopenharmony_ci if (!bio) 1841cb0ef41Sopenharmony_ci return ThrowCryptoError(env, ERR_get_error()); 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ci Local<Object> cert; 1871cb0ef41Sopenharmony_ci 1881cb0ef41Sopenharmony_ci X509Pointer pem(PEM_read_bio_X509_AUX( 1891cb0ef41Sopenharmony_ci bio.get(), nullptr, NoPasswordCallback, nullptr)); 1901cb0ef41Sopenharmony_ci if (!pem) { 1911cb0ef41Sopenharmony_ci // Try as DER, but return the original PEM failure if it isn't DER. 1921cb0ef41Sopenharmony_ci MarkPopErrorOnReturn mark_here; 1931cb0ef41Sopenharmony_ci 1941cb0ef41Sopenharmony_ci X509Pointer der(d2i_X509(nullptr, &data, data_len)); 1951cb0ef41Sopenharmony_ci if (!der) 1961cb0ef41Sopenharmony_ci return ThrowCryptoError(env, ERR_get_error()); 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ci if (!X509Certificate::New(env, std::move(der)).ToLocal(&cert)) 1991cb0ef41Sopenharmony_ci return; 2001cb0ef41Sopenharmony_ci } else if (!X509Certificate::New(env, std::move(pem)).ToLocal(&cert)) { 2011cb0ef41Sopenharmony_ci return; 2021cb0ef41Sopenharmony_ci } 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_ci args.GetReturnValue().Set(cert); 2051cb0ef41Sopenharmony_ci} 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_citemplate <MaybeLocal<Value> Property( 2081cb0ef41Sopenharmony_ci Environment* env, X509* cert, const BIOPointer& bio)> 2091cb0ef41Sopenharmony_cistatic void ReturnPropertyThroughBIO(const FunctionCallbackInfo<Value>& args) { 2101cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 2111cb0ef41Sopenharmony_ci X509Certificate* cert; 2121cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); 2131cb0ef41Sopenharmony_ci BIOPointer bio(BIO_new(BIO_s_mem())); 2141cb0ef41Sopenharmony_ci CHECK(bio); 2151cb0ef41Sopenharmony_ci Local<Value> ret; 2161cb0ef41Sopenharmony_ci if (Property(env, cert->get(), bio).ToLocal(&ret)) 2171cb0ef41Sopenharmony_ci args.GetReturnValue().Set(ret); 2181cb0ef41Sopenharmony_ci} 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_civoid X509Certificate::Subject(const FunctionCallbackInfo<Value>& args) { 2211cb0ef41Sopenharmony_ci ReturnPropertyThroughBIO<GetSubject>(args); 2221cb0ef41Sopenharmony_ci} 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_civoid X509Certificate::Issuer(const FunctionCallbackInfo<Value>& args) { 2251cb0ef41Sopenharmony_ci ReturnPropertyThroughBIO<GetIssuerString>(args); 2261cb0ef41Sopenharmony_ci} 2271cb0ef41Sopenharmony_ci 2281cb0ef41Sopenharmony_civoid X509Certificate::SubjectAltName(const FunctionCallbackInfo<Value>& args) { 2291cb0ef41Sopenharmony_ci ReturnPropertyThroughBIO<GetSubjectAltNameString>(args); 2301cb0ef41Sopenharmony_ci} 2311cb0ef41Sopenharmony_ci 2321cb0ef41Sopenharmony_civoid X509Certificate::InfoAccess(const FunctionCallbackInfo<Value>& args) { 2331cb0ef41Sopenharmony_ci ReturnPropertyThroughBIO<GetInfoAccessString>(args); 2341cb0ef41Sopenharmony_ci} 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_civoid X509Certificate::ValidFrom(const FunctionCallbackInfo<Value>& args) { 2371cb0ef41Sopenharmony_ci ReturnPropertyThroughBIO<GetValidFrom>(args); 2381cb0ef41Sopenharmony_ci} 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_civoid X509Certificate::ValidTo(const FunctionCallbackInfo<Value>& args) { 2411cb0ef41Sopenharmony_ci ReturnPropertyThroughBIO<GetValidTo>(args); 2421cb0ef41Sopenharmony_ci} 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_citemplate <MaybeLocal<Value> Property(Environment* env, X509* cert)> 2451cb0ef41Sopenharmony_cistatic void ReturnProperty(const FunctionCallbackInfo<Value>& args) { 2461cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 2471cb0ef41Sopenharmony_ci X509Certificate* cert; 2481cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); 2491cb0ef41Sopenharmony_ci Local<Value> ret; 2501cb0ef41Sopenharmony_ci if (Property(env, cert->get()).ToLocal(&ret)) args.GetReturnValue().Set(ret); 2511cb0ef41Sopenharmony_ci} 2521cb0ef41Sopenharmony_ci 2531cb0ef41Sopenharmony_civoid X509Certificate::KeyUsage(const FunctionCallbackInfo<Value>& args) { 2541cb0ef41Sopenharmony_ci ReturnProperty<GetKeyUsage>(args); 2551cb0ef41Sopenharmony_ci} 2561cb0ef41Sopenharmony_ci 2571cb0ef41Sopenharmony_civoid X509Certificate::SerialNumber(const FunctionCallbackInfo<Value>& args) { 2581cb0ef41Sopenharmony_ci ReturnProperty<GetSerialNumber>(args); 2591cb0ef41Sopenharmony_ci} 2601cb0ef41Sopenharmony_ci 2611cb0ef41Sopenharmony_civoid X509Certificate::Raw(const FunctionCallbackInfo<Value>& args) { 2621cb0ef41Sopenharmony_ci ReturnProperty<GetRawDERCertificate>(args); 2631cb0ef41Sopenharmony_ci} 2641cb0ef41Sopenharmony_ci 2651cb0ef41Sopenharmony_civoid X509Certificate::PublicKey(const FunctionCallbackInfo<Value>& args) { 2661cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 2671cb0ef41Sopenharmony_ci X509Certificate* cert; 2681cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); 2691cb0ef41Sopenharmony_ci 2701cb0ef41Sopenharmony_ci // TODO(tniessen): consider checking X509_get_pubkey() when the 2711cb0ef41Sopenharmony_ci // X509Certificate object is being created. 2721cb0ef41Sopenharmony_ci ClearErrorOnReturn clear_error_on_return; 2731cb0ef41Sopenharmony_ci EVPKeyPointer pkey(X509_get_pubkey(cert->get())); 2741cb0ef41Sopenharmony_ci if (!pkey) return ThrowCryptoError(env, ERR_get_error()); 2751cb0ef41Sopenharmony_ci ManagedEVPPKey epkey(std::move(pkey)); 2761cb0ef41Sopenharmony_ci std::shared_ptr<KeyObjectData> key_data = 2771cb0ef41Sopenharmony_ci KeyObjectData::CreateAsymmetric(kKeyTypePublic, epkey); 2781cb0ef41Sopenharmony_ci 2791cb0ef41Sopenharmony_ci Local<Value> ret; 2801cb0ef41Sopenharmony_ci if (KeyObjectHandle::Create(env, key_data).ToLocal(&ret)) 2811cb0ef41Sopenharmony_ci args.GetReturnValue().Set(ret); 2821cb0ef41Sopenharmony_ci} 2831cb0ef41Sopenharmony_ci 2841cb0ef41Sopenharmony_civoid X509Certificate::Pem(const FunctionCallbackInfo<Value>& args) { 2851cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 2861cb0ef41Sopenharmony_ci X509Certificate* cert; 2871cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); 2881cb0ef41Sopenharmony_ci BIOPointer bio(BIO_new(BIO_s_mem())); 2891cb0ef41Sopenharmony_ci CHECK(bio); 2901cb0ef41Sopenharmony_ci if (PEM_write_bio_X509(bio.get(), cert->get())) 2911cb0ef41Sopenharmony_ci args.GetReturnValue().Set(ToV8Value(env, bio)); 2921cb0ef41Sopenharmony_ci} 2931cb0ef41Sopenharmony_ci 2941cb0ef41Sopenharmony_civoid X509Certificate::CheckCA(const FunctionCallbackInfo<Value>& args) { 2951cb0ef41Sopenharmony_ci X509Certificate* cert; 2961cb0ef41Sopenharmony_ci ClearErrorOnReturn clear_error_on_return; 2971cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); 2981cb0ef41Sopenharmony_ci args.GetReturnValue().Set(X509_check_ca(cert->get()) == 1); 2991cb0ef41Sopenharmony_ci} 3001cb0ef41Sopenharmony_ci 3011cb0ef41Sopenharmony_civoid X509Certificate::CheckHost(const FunctionCallbackInfo<Value>& args) { 3021cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 3031cb0ef41Sopenharmony_ci X509Certificate* cert; 3041cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_ci CHECK(args[0]->IsString()); // name 3071cb0ef41Sopenharmony_ci CHECK(args[1]->IsUint32()); // flags 3081cb0ef41Sopenharmony_ci 3091cb0ef41Sopenharmony_ci Utf8Value name(env->isolate(), args[0]); 3101cb0ef41Sopenharmony_ci uint32_t flags = args[1].As<Uint32>()->Value(); 3111cb0ef41Sopenharmony_ci char* peername; 3121cb0ef41Sopenharmony_ci 3131cb0ef41Sopenharmony_ci switch (X509_check_host( 3141cb0ef41Sopenharmony_ci cert->get(), 3151cb0ef41Sopenharmony_ci *name, 3161cb0ef41Sopenharmony_ci name.length(), 3171cb0ef41Sopenharmony_ci flags, 3181cb0ef41Sopenharmony_ci &peername)) { 3191cb0ef41Sopenharmony_ci case 1: { // Match! 3201cb0ef41Sopenharmony_ci Local<Value> ret = args[0]; 3211cb0ef41Sopenharmony_ci if (peername != nullptr) { 3221cb0ef41Sopenharmony_ci ret = OneByteString(env->isolate(), peername); 3231cb0ef41Sopenharmony_ci OPENSSL_free(peername); 3241cb0ef41Sopenharmony_ci } 3251cb0ef41Sopenharmony_ci return args.GetReturnValue().Set(ret); 3261cb0ef41Sopenharmony_ci } 3271cb0ef41Sopenharmony_ci case 0: // No Match! 3281cb0ef41Sopenharmony_ci return; // No return value is set 3291cb0ef41Sopenharmony_ci case -2: // Error! 3301cb0ef41Sopenharmony_ci return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid name"); 3311cb0ef41Sopenharmony_ci default: // Error! 3321cb0ef41Sopenharmony_ci return THROW_ERR_CRYPTO_OPERATION_FAILED(env); 3331cb0ef41Sopenharmony_ci } 3341cb0ef41Sopenharmony_ci} 3351cb0ef41Sopenharmony_ci 3361cb0ef41Sopenharmony_civoid X509Certificate::CheckEmail(const FunctionCallbackInfo<Value>& args) { 3371cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 3381cb0ef41Sopenharmony_ci X509Certificate* cert; 3391cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); 3401cb0ef41Sopenharmony_ci 3411cb0ef41Sopenharmony_ci CHECK(args[0]->IsString()); // name 3421cb0ef41Sopenharmony_ci CHECK(args[1]->IsUint32()); // flags 3431cb0ef41Sopenharmony_ci 3441cb0ef41Sopenharmony_ci Utf8Value name(env->isolate(), args[0]); 3451cb0ef41Sopenharmony_ci uint32_t flags = args[1].As<Uint32>()->Value(); 3461cb0ef41Sopenharmony_ci 3471cb0ef41Sopenharmony_ci switch (X509_check_email( 3481cb0ef41Sopenharmony_ci cert->get(), 3491cb0ef41Sopenharmony_ci *name, 3501cb0ef41Sopenharmony_ci name.length(), 3511cb0ef41Sopenharmony_ci flags)) { 3521cb0ef41Sopenharmony_ci case 1: // Match! 3531cb0ef41Sopenharmony_ci return args.GetReturnValue().Set(args[0]); 3541cb0ef41Sopenharmony_ci case 0: // No Match! 3551cb0ef41Sopenharmony_ci return; // No return value is set 3561cb0ef41Sopenharmony_ci case -2: // Error! 3571cb0ef41Sopenharmony_ci return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid name"); 3581cb0ef41Sopenharmony_ci default: // Error! 3591cb0ef41Sopenharmony_ci return THROW_ERR_CRYPTO_OPERATION_FAILED(env); 3601cb0ef41Sopenharmony_ci } 3611cb0ef41Sopenharmony_ci} 3621cb0ef41Sopenharmony_ci 3631cb0ef41Sopenharmony_civoid X509Certificate::CheckIP(const FunctionCallbackInfo<Value>& args) { 3641cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 3651cb0ef41Sopenharmony_ci X509Certificate* cert; 3661cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); 3671cb0ef41Sopenharmony_ci 3681cb0ef41Sopenharmony_ci CHECK(args[0]->IsString()); // IP 3691cb0ef41Sopenharmony_ci CHECK(args[1]->IsUint32()); // flags 3701cb0ef41Sopenharmony_ci 3711cb0ef41Sopenharmony_ci Utf8Value name(env->isolate(), args[0]); 3721cb0ef41Sopenharmony_ci uint32_t flags = args[1].As<Uint32>()->Value(); 3731cb0ef41Sopenharmony_ci 3741cb0ef41Sopenharmony_ci switch (X509_check_ip_asc(cert->get(), *name, flags)) { 3751cb0ef41Sopenharmony_ci case 1: // Match! 3761cb0ef41Sopenharmony_ci return args.GetReturnValue().Set(args[0]); 3771cb0ef41Sopenharmony_ci case 0: // No Match! 3781cb0ef41Sopenharmony_ci return; // No return value is set 3791cb0ef41Sopenharmony_ci case -2: // Error! 3801cb0ef41Sopenharmony_ci return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid IP"); 3811cb0ef41Sopenharmony_ci default: // Error! 3821cb0ef41Sopenharmony_ci return THROW_ERR_CRYPTO_OPERATION_FAILED(env); 3831cb0ef41Sopenharmony_ci } 3841cb0ef41Sopenharmony_ci} 3851cb0ef41Sopenharmony_ci 3861cb0ef41Sopenharmony_civoid X509Certificate::CheckIssued(const FunctionCallbackInfo<Value>& args) { 3871cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 3881cb0ef41Sopenharmony_ci X509Certificate* cert; 3891cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ci CHECK(args[0]->IsObject()); 3921cb0ef41Sopenharmony_ci CHECK(X509Certificate::HasInstance(env, args[0].As<Object>())); 3931cb0ef41Sopenharmony_ci 3941cb0ef41Sopenharmony_ci X509Certificate* issuer; 3951cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&issuer, args[0]); 3961cb0ef41Sopenharmony_ci 3971cb0ef41Sopenharmony_ci ClearErrorOnReturn clear_error_on_return; 3981cb0ef41Sopenharmony_ci 3991cb0ef41Sopenharmony_ci args.GetReturnValue().Set( 4001cb0ef41Sopenharmony_ci X509_check_issued(issuer->get(), cert->get()) == X509_V_OK); 4011cb0ef41Sopenharmony_ci} 4021cb0ef41Sopenharmony_ci 4031cb0ef41Sopenharmony_civoid X509Certificate::CheckPrivateKey(const FunctionCallbackInfo<Value>& args) { 4041cb0ef41Sopenharmony_ci X509Certificate* cert; 4051cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); 4061cb0ef41Sopenharmony_ci 4071cb0ef41Sopenharmony_ci CHECK(args[0]->IsObject()); 4081cb0ef41Sopenharmony_ci KeyObjectHandle* key; 4091cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&key, args[0]); 4101cb0ef41Sopenharmony_ci CHECK_EQ(key->Data()->GetKeyType(), kKeyTypePrivate); 4111cb0ef41Sopenharmony_ci 4121cb0ef41Sopenharmony_ci ClearErrorOnReturn clear_error_on_return; 4131cb0ef41Sopenharmony_ci 4141cb0ef41Sopenharmony_ci args.GetReturnValue().Set( 4151cb0ef41Sopenharmony_ci X509_check_private_key( 4161cb0ef41Sopenharmony_ci cert->get(), 4171cb0ef41Sopenharmony_ci key->Data()->GetAsymmetricKey().get()) == 1); 4181cb0ef41Sopenharmony_ci} 4191cb0ef41Sopenharmony_ci 4201cb0ef41Sopenharmony_civoid X509Certificate::Verify(const FunctionCallbackInfo<Value>& args) { 4211cb0ef41Sopenharmony_ci X509Certificate* cert; 4221cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); 4231cb0ef41Sopenharmony_ci 4241cb0ef41Sopenharmony_ci CHECK(args[0]->IsObject()); 4251cb0ef41Sopenharmony_ci KeyObjectHandle* key; 4261cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&key, args[0]); 4271cb0ef41Sopenharmony_ci CHECK_EQ(key->Data()->GetKeyType(), kKeyTypePublic); 4281cb0ef41Sopenharmony_ci 4291cb0ef41Sopenharmony_ci ClearErrorOnReturn clear_error_on_return; 4301cb0ef41Sopenharmony_ci 4311cb0ef41Sopenharmony_ci args.GetReturnValue().Set( 4321cb0ef41Sopenharmony_ci X509_verify( 4331cb0ef41Sopenharmony_ci cert->get(), 4341cb0ef41Sopenharmony_ci key->Data()->GetAsymmetricKey().get()) > 0); 4351cb0ef41Sopenharmony_ci} 4361cb0ef41Sopenharmony_ci 4371cb0ef41Sopenharmony_civoid X509Certificate::ToLegacy(const FunctionCallbackInfo<Value>& args) { 4381cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 4391cb0ef41Sopenharmony_ci X509Certificate* cert; 4401cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); 4411cb0ef41Sopenharmony_ci ClearErrorOnReturn clear_error_on_return; 4421cb0ef41Sopenharmony_ci Local<Value> ret; 4431cb0ef41Sopenharmony_ci if (X509ToObject(env, cert->get()).ToLocal(&ret)) 4441cb0ef41Sopenharmony_ci args.GetReturnValue().Set(ret); 4451cb0ef41Sopenharmony_ci} 4461cb0ef41Sopenharmony_ci 4471cb0ef41Sopenharmony_civoid X509Certificate::GetIssuerCert(const FunctionCallbackInfo<Value>& args) { 4481cb0ef41Sopenharmony_ci X509Certificate* cert; 4491cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); 4501cb0ef41Sopenharmony_ci if (cert->issuer_cert_) 4511cb0ef41Sopenharmony_ci args.GetReturnValue().Set(cert->issuer_cert_->object()); 4521cb0ef41Sopenharmony_ci} 4531cb0ef41Sopenharmony_ci 4541cb0ef41Sopenharmony_ciX509Certificate::X509Certificate( 4551cb0ef41Sopenharmony_ci Environment* env, 4561cb0ef41Sopenharmony_ci Local<Object> object, 4571cb0ef41Sopenharmony_ci std::shared_ptr<ManagedX509> cert, 4581cb0ef41Sopenharmony_ci STACK_OF(X509)* issuer_chain) 4591cb0ef41Sopenharmony_ci : BaseObject(env, object), 4601cb0ef41Sopenharmony_ci cert_(std::move(cert)) { 4611cb0ef41Sopenharmony_ci MakeWeak(); 4621cb0ef41Sopenharmony_ci 4631cb0ef41Sopenharmony_ci if (issuer_chain != nullptr && sk_X509_num(issuer_chain)) { 4641cb0ef41Sopenharmony_ci X509Pointer cert(X509_dup(sk_X509_value(issuer_chain, 0))); 4651cb0ef41Sopenharmony_ci sk_X509_delete(issuer_chain, 0); 4661cb0ef41Sopenharmony_ci Local<Object> obj = sk_X509_num(issuer_chain) 4671cb0ef41Sopenharmony_ci ? X509Certificate::New(env, std::move(cert), issuer_chain) 4681cb0ef41Sopenharmony_ci .ToLocalChecked() 4691cb0ef41Sopenharmony_ci : X509Certificate::New(env, std::move(cert)) 4701cb0ef41Sopenharmony_ci .ToLocalChecked(); 4711cb0ef41Sopenharmony_ci issuer_cert_.reset(Unwrap<X509Certificate>(obj)); 4721cb0ef41Sopenharmony_ci } 4731cb0ef41Sopenharmony_ci} 4741cb0ef41Sopenharmony_ci 4751cb0ef41Sopenharmony_civoid X509Certificate::MemoryInfo(MemoryTracker* tracker) const { 4761cb0ef41Sopenharmony_ci tracker->TrackField("cert", cert_); 4771cb0ef41Sopenharmony_ci} 4781cb0ef41Sopenharmony_ci 4791cb0ef41Sopenharmony_ciBaseObjectPtr<BaseObject> 4801cb0ef41Sopenharmony_ciX509Certificate::X509CertificateTransferData::Deserialize( 4811cb0ef41Sopenharmony_ci Environment* env, 4821cb0ef41Sopenharmony_ci Local<Context> context, 4831cb0ef41Sopenharmony_ci std::unique_ptr<worker::TransferData> self) { 4841cb0ef41Sopenharmony_ci if (context != env->context()) { 4851cb0ef41Sopenharmony_ci THROW_ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE(env); 4861cb0ef41Sopenharmony_ci return {}; 4871cb0ef41Sopenharmony_ci } 4881cb0ef41Sopenharmony_ci 4891cb0ef41Sopenharmony_ci Local<Value> handle; 4901cb0ef41Sopenharmony_ci if (!X509Certificate::New(env, data_).ToLocal(&handle)) 4911cb0ef41Sopenharmony_ci return {}; 4921cb0ef41Sopenharmony_ci 4931cb0ef41Sopenharmony_ci return BaseObjectPtr<BaseObject>( 4941cb0ef41Sopenharmony_ci Unwrap<X509Certificate>(handle.As<Object>())); 4951cb0ef41Sopenharmony_ci} 4961cb0ef41Sopenharmony_ci 4971cb0ef41Sopenharmony_ci 4981cb0ef41Sopenharmony_ciBaseObject::TransferMode X509Certificate::GetTransferMode() const { 4991cb0ef41Sopenharmony_ci return BaseObject::TransferMode::kCloneable; 5001cb0ef41Sopenharmony_ci} 5011cb0ef41Sopenharmony_ci 5021cb0ef41Sopenharmony_cistd::unique_ptr<worker::TransferData> X509Certificate::CloneForMessaging() 5031cb0ef41Sopenharmony_ci const { 5041cb0ef41Sopenharmony_ci return std::make_unique<X509CertificateTransferData>(cert_); 5051cb0ef41Sopenharmony_ci} 5061cb0ef41Sopenharmony_ci 5071cb0ef41Sopenharmony_ci 5081cb0ef41Sopenharmony_civoid X509Certificate::Initialize(Environment* env, Local<Object> target) { 5091cb0ef41Sopenharmony_ci SetMethod(env->context(), target, "parseX509", X509Certificate::Parse); 5101cb0ef41Sopenharmony_ci 5111cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT); 5121cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_NEVER_CHECK_SUBJECT); 5131cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_NO_WILDCARDS); 5141cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); 5151cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS); 5161cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS); 5171cb0ef41Sopenharmony_ci} 5181cb0ef41Sopenharmony_ci 5191cb0ef41Sopenharmony_civoid X509Certificate::RegisterExternalReferences( 5201cb0ef41Sopenharmony_ci ExternalReferenceRegistry* registry) { 5211cb0ef41Sopenharmony_ci registry->Register(X509Certificate::Parse); 5221cb0ef41Sopenharmony_ci registry->Register(Subject); 5231cb0ef41Sopenharmony_ci registry->Register(SubjectAltName); 5241cb0ef41Sopenharmony_ci registry->Register(InfoAccess); 5251cb0ef41Sopenharmony_ci registry->Register(Issuer); 5261cb0ef41Sopenharmony_ci registry->Register(ValidTo); 5271cb0ef41Sopenharmony_ci registry->Register(ValidFrom); 5281cb0ef41Sopenharmony_ci registry->Register(Fingerprint<EVP_sha1>); 5291cb0ef41Sopenharmony_ci registry->Register(Fingerprint<EVP_sha256>); 5301cb0ef41Sopenharmony_ci registry->Register(Fingerprint<EVP_sha512>); 5311cb0ef41Sopenharmony_ci registry->Register(KeyUsage); 5321cb0ef41Sopenharmony_ci registry->Register(SerialNumber); 5331cb0ef41Sopenharmony_ci registry->Register(Pem); 5341cb0ef41Sopenharmony_ci registry->Register(Raw); 5351cb0ef41Sopenharmony_ci registry->Register(PublicKey); 5361cb0ef41Sopenharmony_ci registry->Register(CheckCA); 5371cb0ef41Sopenharmony_ci registry->Register(CheckHost); 5381cb0ef41Sopenharmony_ci registry->Register(CheckEmail); 5391cb0ef41Sopenharmony_ci registry->Register(CheckIP); 5401cb0ef41Sopenharmony_ci registry->Register(CheckIssued); 5411cb0ef41Sopenharmony_ci registry->Register(CheckPrivateKey); 5421cb0ef41Sopenharmony_ci registry->Register(Verify); 5431cb0ef41Sopenharmony_ci registry->Register(ToLegacy); 5441cb0ef41Sopenharmony_ci registry->Register(GetIssuerCert); 5451cb0ef41Sopenharmony_ci} 5461cb0ef41Sopenharmony_ci} // namespace crypto 5471cb0ef41Sopenharmony_ci} // namespace node 548