@@ -185,6 +185,72 @@ Handle<Value> SecureContext::SetKey(const Arguments& args) {
185185}
186186
187187
188+ // Read a file that contains our certificate in "PEM" format,
189+ // possibly followed by a sequence of CA certificates that should be
190+ // sent to the peer in the Certificate message.
191+ //
192+ // Taken from OpenSSL - editted for style.
193+ int SSL_CTX_use_certificate_chain (SSL_CTX *ctx, BIO *in) {
194+ int ret = 0 ;
195+ X509 *x = NULL ;
196+
197+ x = PEM_read_bio_X509_AUX (in, NULL , NULL , NULL );
198+
199+ if (x == NULL ) {
200+ SSLerr (SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE , ERR_R_PEM_LIB );
201+ goto end;
202+ }
203+
204+ ret = SSL_CTX_use_certificate (ctx, x);
205+
206+ if (ERR_peek_error () != 0 ) {
207+ // Key/certificate mismatch doesn't imply ret==0 ...
208+ ret = 0 ;
209+ }
210+
211+ if (ret) {
212+ // If we could set up our certificate, now proceed to
213+ // the CA certificates.
214+ X509 *ca;
215+ int r;
216+ unsigned long err;
217+
218+ if (ctx->extra_certs != NULL ) {
219+ sk_X509_pop_free (ctx->extra_certs , X509_free);
220+ ctx->extra_certs = NULL ;
221+ }
222+
223+ while ((ca = PEM_read_bio_X509 (in, NULL , NULL , NULL ))) {
224+ r = SSL_CTX_add_extra_chain_cert (ctx, ca);
225+
226+ if (!r) {
227+ X509_free (ca);
228+ ret = 0 ;
229+ goto end;
230+ }
231+ // Note that we must not free r if it was successfully
232+ // added to the chain (while we must free the main
233+ // certificate, since its reference count is increased
234+ // by SSL_CTX_use_certificate).
235+ }
236+
237+ // When the while loop ends, it's usually just EOF.
238+ err = ERR_peek_last_error ();
239+ if (ERR_GET_LIB (err) == ERR_LIB_PEM &&
240+ ERR_GET_REASON (err) == PEM_R_NO_START_LINE ) {
241+ ERR_clear_error ();
242+ } else {
243+ // some real error
244+ ret = 0 ;
245+ }
246+ }
247+
248+ end:
249+ if (x != NULL ) X509_free (x);
250+ return ret;
251+ }
252+
253+
188254Handle<Value> SecureContext::SetCert (const Arguments& args) {
189255 HandleScope scope;
190256
@@ -195,11 +261,23 @@ Handle<Value> SecureContext::SetCert(const Arguments& args) {
195261 String::New (" Bad parameter" )));
196262 }
197263
198- X509 * x509 = LoadX509 (args[0 ]);
199- if (!x509 ) return False ();
264+ BIO * bio = LoadBIO (args[0 ]);
265+ if (!bio ) return False ();
200266
201- SSL_CTX_use_certificate (sc->ctx_ , x509);
202- X509_free (x509);
267+ int rv = SSL_CTX_use_certificate_chain (sc->ctx_ , bio);
268+
269+ BIO_free (bio);
270+
271+ if (!rv) {
272+ unsigned long err = ERR_get_error ();
273+ if (!err) {
274+ return ThrowException (Exception::Error (
275+ String::New (" SSL_CTX_use_certificate_chain" )));
276+ }
277+ char string[120 ];
278+ ERR_error_string (err, string);
279+ return ThrowException (Exception::Error (String::New (string)));
280+ }
203281
204282 return True ();
205283}
@@ -1233,9 +1311,9 @@ class Cipher : public ObjectWrap {
12331311 EVP_CIPHER_CTX_init (&ctx);
12341312 EVP_CipherInit (&ctx,cipher,(unsigned char *)key,(unsigned char *)iv, true );
12351313 if (!EVP_CIPHER_CTX_set_key_length (&ctx,key_len)) {
1236- fprintf (stderr, " node-crypto : Invalid key length %d\n " , key_len);
1237- EVP_CIPHER_CTX_cleanup (&ctx);
1238- return false ;
1314+ fprintf (stderr, " node-crypto : Invalid key length %d\n " , key_len);
1315+ EVP_CIPHER_CTX_cleanup (&ctx);
1316+ return false ;
12391317 }
12401318 initialised_ = true ;
12411319 return true ;
@@ -1253,15 +1331,15 @@ class Cipher : public ObjectWrap {
12531331 return false ;
12541332 }
12551333 if (EVP_CIPHER_iv_length (cipher)!=iv_len) {
1256- fprintf (stderr, " node-crypto : Invalid IV length %d\n " , iv_len);
1334+ fprintf (stderr, " node-crypto : Invalid IV length %d\n " , iv_len);
12571335 return false ;
12581336 }
12591337 EVP_CIPHER_CTX_init (&ctx);
12601338 EVP_CipherInit (&ctx,cipher,(unsigned char *)key,(unsigned char *)iv, true );
12611339 if (!EVP_CIPHER_CTX_set_key_length (&ctx,key_len)) {
1262- fprintf (stderr, " node-crypto : Invalid key length %d\n " , key_len);
1263- EVP_CIPHER_CTX_cleanup (&ctx);
1264- return false ;
1340+ fprintf (stderr, " node-crypto : Invalid key length %d\n " , key_len);
1341+ EVP_CIPHER_CTX_cleanup (&ctx);
1342+ return false ;
12651343 }
12661344 initialised_ = true ;
12671345 return true ;
@@ -1336,7 +1414,7 @@ class Cipher : public ObjectWrap {
13361414
13371415 static Handle<Value> CipherInitIv (const Arguments& args) {
13381416 Cipher *cipher = ObjectWrap::Unwrap<Cipher>(args.This ());
1339-
1417+
13401418 HandleScope scope;
13411419
13421420 cipher->incomplete_base64 =NULL ;
@@ -1368,7 +1446,7 @@ class Cipher : public ObjectWrap {
13681446 assert (iv_written == iv_len);
13691447
13701448 String::Utf8Value cipherType (args[0 ]->ToString ());
1371-
1449+
13721450 bool r = cipher->CipherInitIv (*cipherType, key_buf,key_len,iv_buf,iv_len);
13731451
13741452 delete [] key_buf;
@@ -1421,19 +1499,19 @@ class Cipher : public ObjectWrap {
14211499 if (out_len==0 ) {
14221500 outString=String::New (" " );
14231501 } else {
1424- if (args.Length () <= 2 || !args[2 ]->IsString ()) {
1425- // Binary
1426- outString = Encode (out, out_len, BINARY );
1427- } else {
1428- char * out_hexdigest;
1429- int out_hex_len;
1430- String::Utf8Value encoding (args[2 ]->ToString ());
1431- if (strcasecmp (*encoding, " hex" ) == 0 ) {
1432- // Hex encoding
1433- HexEncode (out, out_len, &out_hexdigest, &out_hex_len);
1434- outString = Encode (out_hexdigest, out_hex_len, BINARY );
1435- delete [] out_hexdigest;
1436- } else if (strcasecmp (*encoding, " base64" ) == 0 ) {
1502+ if (args.Length () <= 2 || !args[2 ]->IsString ()) {
1503+ // Binary
1504+ outString = Encode (out, out_len, BINARY );
1505+ } else {
1506+ char * out_hexdigest;
1507+ int out_hex_len;
1508+ String::Utf8Value encoding (args[2 ]->ToString ());
1509+ if (strcasecmp (*encoding, " hex" ) == 0 ) {
1510+ // Hex encoding
1511+ HexEncode (out, out_len, &out_hexdigest, &out_hex_len);
1512+ outString = Encode (out_hexdigest, out_hex_len, BINARY );
1513+ delete [] out_hexdigest;
1514+ } else if (strcasecmp (*encoding, " base64" ) == 0 ) {
14371515 // Base64 encoding
14381516 // Check to see if we need to add in previous base64 overhang
14391517 if (cipher->incomplete_base64 !=NULL ){
@@ -1460,16 +1538,16 @@ class Cipher : public ObjectWrap {
14601538 out[out_len]=0 ;
14611539 }
14621540
1463- base64 (out, out_len, &out_hexdigest, &out_hex_len);
1464- outString = Encode (out_hexdigest, out_hex_len, BINARY );
1465- delete [] out_hexdigest;
1466- } else if (strcasecmp (*encoding, " binary" ) == 0 ) {
1467- outString = Encode (out, out_len, BINARY );
1468- } else {
1541+ base64 (out, out_len, &out_hexdigest, &out_hex_len);
1542+ outString = Encode (out_hexdigest, out_hex_len, BINARY );
1543+ delete [] out_hexdigest;
1544+ } else if (strcasecmp (*encoding, " binary" ) == 0 ) {
1545+ outString = Encode (out, out_len, BINARY );
1546+ } else {
14691547 fprintf (stderr, " node-crypto : Cipher .update encoding "
14701548 " can be binary, hex or base64\n " );
1471- }
1472- }
1549+ }
1550+ }
14731551 }
14741552
14751553 if (out) delete [] out;
@@ -1585,9 +1663,9 @@ class Decipher : public ObjectWrap {
15851663 (unsigned char *)(iv),
15861664 false );
15871665 if (!EVP_CIPHER_CTX_set_key_length (&ctx,key_len)) {
1588- fprintf (stderr, " node-crypto : Invalid key length %d\n " , key_len);
1589- EVP_CIPHER_CTX_cleanup (&ctx);
1590- return false ;
1666+ fprintf (stderr, " node-crypto : Invalid key length %d\n " , key_len);
1667+ EVP_CIPHER_CTX_cleanup (&ctx);
1668+ return false ;
15911669 }
15921670 initialised_ = true ;
15931671 return true ;
@@ -1605,7 +1683,7 @@ class Decipher : public ObjectWrap {
16051683 return false ;
16061684 }
16071685 if (EVP_CIPHER_iv_length (cipher_) != iv_len) {
1608- fprintf (stderr, " node-crypto : Invalid IV length %d\n " , iv_len);
1686+ fprintf (stderr, " node-crypto : Invalid IV length %d\n " , iv_len);
16091687 return false ;
16101688 }
16111689 EVP_CIPHER_CTX_init (&ctx);
@@ -1615,9 +1693,9 @@ class Decipher : public ObjectWrap {
16151693 (unsigned char *)(iv),
16161694 false );
16171695 if (!EVP_CIPHER_CTX_set_key_length (&ctx,key_len)) {
1618- fprintf (stderr, " node-crypto : Invalid key length %d\n " , key_len);
1619- EVP_CIPHER_CTX_cleanup (&ctx);
1620- return false ;
1696+ fprintf (stderr, " node-crypto : Invalid key length %d\n " , key_len);
1697+ EVP_CIPHER_CTX_cleanup (&ctx);
1698+ return false ;
16211699 }
16221700 initialised_ = true ;
16231701 return true ;
@@ -1659,7 +1737,7 @@ class Decipher : public ObjectWrap {
16591737
16601738 static Handle<Value> DecipherInit (const Arguments& args) {
16611739 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This ());
1662-
1740+
16631741 HandleScope scope;
16641742
16651743 cipher->incomplete_utf8 =NULL ;
@@ -1682,7 +1760,7 @@ class Decipher : public ObjectWrap {
16821760 assert (key_written == key_len);
16831761
16841762 String::Utf8Value cipherType (args[0 ]->ToString ());
1685-
1763+
16861764 bool r = cipher->DecipherInit (*cipherType, key_buf,key_len);
16871765
16881766 delete [] key_buf;
@@ -1696,7 +1774,7 @@ class Decipher : public ObjectWrap {
16961774
16971775 static Handle<Value> DecipherInitIv (const Arguments& args) {
16981776 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This ());
1699-
1777+
17001778 HandleScope scope;
17011779
17021780 cipher->incomplete_utf8 =NULL ;
@@ -1730,7 +1808,7 @@ class Decipher : public ObjectWrap {
17301808 assert (iv_written == iv_len);
17311809
17321810 String::Utf8Value cipherType (args[0 ]->ToString ());
1733-
1811+
17341812 bool r = cipher->DecipherInitIv (*cipherType, key_buf,key_len,iv_buf,iv_len);
17351813
17361814 delete [] key_buf;
@@ -2087,7 +2165,7 @@ class Hmac : public ObjectWrap {
20872165 }
20882166
20892167 int r;
2090-
2168+
20912169 if ( Buffer::HasInstance (args[0 ])) {
20922170 Local<Object> buffer_obj = args[0 ]->ToObject ();
20932171 char *buffer_data = Buffer::Data (buffer_obj);
0 commit comments