server_credentials.cc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. *
  3. * Copyright 2015 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #include <node.h>
  19. #include "grpc/grpc.h"
  20. #include "grpc/grpc_security.h"
  21. #include "grpc/support/log.h"
  22. #include "server_credentials.h"
  23. namespace grpc {
  24. namespace node {
  25. using Nan::Callback;
  26. using Nan::EscapableHandleScope;
  27. using Nan::HandleScope;
  28. using Nan::Maybe;
  29. using Nan::MaybeLocal;
  30. using Nan::ObjectWrap;
  31. using Nan::Persistent;
  32. using Nan::Utf8String;
  33. using v8::Array;
  34. using v8::Exception;
  35. using v8::External;
  36. using v8::Function;
  37. using v8::FunctionTemplate;
  38. using v8::Integer;
  39. using v8::Local;
  40. using v8::Object;
  41. using v8::ObjectTemplate;
  42. using v8::String;
  43. using v8::Value;
  44. Nan::Callback *ServerCredentials::constructor;
  45. Persistent<FunctionTemplate> ServerCredentials::fun_tpl;
  46. ServerCredentials::ServerCredentials(grpc_server_credentials *credentials)
  47. : wrapped_credentials(credentials) {}
  48. ServerCredentials::~ServerCredentials() {
  49. grpc_server_credentials_release(wrapped_credentials);
  50. }
  51. void ServerCredentials::Init(Local<Object> exports) {
  52. Nan::HandleScope scope;
  53. Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
  54. tpl->SetClassName(Nan::New("ServerCredentials").ToLocalChecked());
  55. tpl->InstanceTemplate()->SetInternalFieldCount(1);
  56. Local<Function> ctr = tpl->GetFunction();
  57. Nan::Set(
  58. ctr, Nan::New("createSsl").ToLocalChecked(),
  59. Nan::GetFunction(Nan::New<FunctionTemplate>(CreateSsl)).ToLocalChecked());
  60. Nan::Set(ctr, Nan::New("createInsecure").ToLocalChecked(),
  61. Nan::GetFunction(Nan::New<FunctionTemplate>(CreateInsecure))
  62. .ToLocalChecked());
  63. fun_tpl.Reset(tpl);
  64. constructor = new Nan::Callback(ctr);
  65. Nan::Set(exports, Nan::New("ServerCredentials").ToLocalChecked(), ctr);
  66. }
  67. bool ServerCredentials::HasInstance(Local<Value> val) {
  68. Nan::HandleScope scope;
  69. return Nan::New(fun_tpl)->HasInstance(val);
  70. }
  71. Local<Value> ServerCredentials::WrapStruct(
  72. grpc_server_credentials *credentials) {
  73. Nan::EscapableHandleScope scope;
  74. const int argc = 1;
  75. Local<Value> argv[argc] = {
  76. Nan::New<External>(reinterpret_cast<void *>(credentials))};
  77. MaybeLocal<Object> maybe_instance =
  78. Nan::NewInstance(constructor->GetFunction(), argc, argv);
  79. if (maybe_instance.IsEmpty()) {
  80. return scope.Escape(Nan::Null());
  81. } else {
  82. return scope.Escape(maybe_instance.ToLocalChecked());
  83. }
  84. }
  85. grpc_server_credentials *ServerCredentials::GetWrappedServerCredentials() {
  86. return wrapped_credentials;
  87. }
  88. NAN_METHOD(ServerCredentials::New) {
  89. if (info.IsConstructCall()) {
  90. if (!info[0]->IsExternal()) {
  91. return Nan::ThrowTypeError(
  92. "ServerCredentials can only be created with the provided functions");
  93. }
  94. Local<External> ext = info[0].As<External>();
  95. grpc_server_credentials *creds_value =
  96. reinterpret_cast<grpc_server_credentials *>(ext->Value());
  97. ServerCredentials *credentials = new ServerCredentials(creds_value);
  98. credentials->Wrap(info.This());
  99. info.GetReturnValue().Set(info.This());
  100. } else {
  101. // This should never be called directly
  102. return Nan::ThrowTypeError(
  103. "ServerCredentials can only be created with the provided functions");
  104. }
  105. }
  106. NAN_METHOD(ServerCredentials::CreateSsl) {
  107. Nan::HandleScope scope;
  108. char *root_certs = NULL;
  109. if (::node::Buffer::HasInstance(info[0])) {
  110. root_certs = ::node::Buffer::Data(info[0]);
  111. } else if (!(info[0]->IsNull() || info[0]->IsUndefined())) {
  112. return Nan::ThrowTypeError(
  113. "createSSl's first argument must be a Buffer if provided");
  114. }
  115. if (!info[1]->IsArray()) {
  116. return Nan::ThrowTypeError(
  117. "createSsl's second argument must be a list of objects");
  118. }
  119. // Default to not requesting the client certificate
  120. grpc_ssl_client_certificate_request_type client_certificate_request =
  121. GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE;
  122. if (info[2]->IsBoolean()) {
  123. client_certificate_request =
  124. Nan::To<bool>(info[2]).FromJust()
  125. ? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
  126. : GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE;
  127. } else if (!(info[2]->IsUndefined() || info[2]->IsNull())) {
  128. return Nan::ThrowTypeError(
  129. "createSsl's third argument must be a boolean if provided");
  130. }
  131. Local<Array> pair_list = Local<Array>::Cast(info[1]);
  132. uint32_t key_cert_pair_count = pair_list->Length();
  133. grpc_ssl_pem_key_cert_pair *key_cert_pairs =
  134. new grpc_ssl_pem_key_cert_pair[key_cert_pair_count];
  135. Local<String> key_key = Nan::New("private_key").ToLocalChecked();
  136. Local<String> cert_key = Nan::New("cert_chain").ToLocalChecked();
  137. for (uint32_t i = 0; i < key_cert_pair_count; i++) {
  138. Local<Value> pair_val = Nan::Get(pair_list, i).ToLocalChecked();
  139. if (!pair_val->IsObject()) {
  140. delete[] key_cert_pairs;
  141. return Nan::ThrowTypeError("Key/cert pairs must be objects");
  142. }
  143. Local<Object> pair_obj = Nan::To<Object>(pair_val).ToLocalChecked();
  144. Local<Value> maybe_key = Nan::Get(pair_obj, key_key).ToLocalChecked();
  145. Local<Value> maybe_cert = Nan::Get(pair_obj, cert_key).ToLocalChecked();
  146. if (!::node::Buffer::HasInstance(maybe_key)) {
  147. delete[] key_cert_pairs;
  148. return Nan::ThrowTypeError("private_key must be a Buffer");
  149. }
  150. if (!::node::Buffer::HasInstance(maybe_cert)) {
  151. delete[] key_cert_pairs;
  152. return Nan::ThrowTypeError("cert_chain must be a Buffer");
  153. }
  154. key_cert_pairs[i].private_key = ::node::Buffer::Data(maybe_key);
  155. key_cert_pairs[i].cert_chain = ::node::Buffer::Data(maybe_cert);
  156. }
  157. grpc_server_credentials *creds = grpc_ssl_server_credentials_create_ex(
  158. root_certs, key_cert_pairs, key_cert_pair_count,
  159. client_certificate_request, NULL);
  160. delete[] key_cert_pairs;
  161. if (creds == NULL) {
  162. info.GetReturnValue().SetNull();
  163. } else {
  164. info.GetReturnValue().Set(WrapStruct(creds));
  165. }
  166. }
  167. NAN_METHOD(ServerCredentials::CreateInsecure) {
  168. info.GetReturnValue().Set(WrapStruct(NULL));
  169. }
  170. } // namespace node
  171. } // namespace grpc