@electerm/ssh2 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/protocol/SFTP.js +94 -7
- package/lib/protocol/crypto/src/binding.cc +222 -102
- package/package.json +1 -1
package/lib/protocol/SFTP.js
CHANGED
|
@@ -1596,6 +1596,91 @@ class SFTP extends EventEmitter {
|
|
|
1596
1596
|
this._debug(`SFTP: Outbound: ${status} expand-path@openssh.com`);
|
|
1597
1597
|
}
|
|
1598
1598
|
}
|
|
1599
|
+
ext_copy_data(srcHandle, srcOffset, len, dstHandle, dstOffset, cb) {
|
|
1600
|
+
if (this.server)
|
|
1601
|
+
throw new Error('Client-only method called in server mode');
|
|
1602
|
+
|
|
1603
|
+
const ext = this._extensions['copy-data'];
|
|
1604
|
+
if (ext !== '1')
|
|
1605
|
+
throw new Error('Server does not support this extended request');
|
|
1606
|
+
|
|
1607
|
+
if (!Buffer.isBuffer(srcHandle))
|
|
1608
|
+
throw new Error('Source handle is not a Buffer');
|
|
1609
|
+
|
|
1610
|
+
if (!Buffer.isBuffer(dstHandle))
|
|
1611
|
+
throw new Error('Destination handle is not a Buffer');
|
|
1612
|
+
|
|
1613
|
+
/*
|
|
1614
|
+
uint32 id
|
|
1615
|
+
string "copy-data"
|
|
1616
|
+
string read-from-handle
|
|
1617
|
+
uint64 read-from-offset
|
|
1618
|
+
uint64 read-data-length
|
|
1619
|
+
string write-to-handle
|
|
1620
|
+
uint64 write-to-offset
|
|
1621
|
+
*/
|
|
1622
|
+
let p = 0;
|
|
1623
|
+
const buf = Buffer.allocUnsafe(
|
|
1624
|
+
4 + 1
|
|
1625
|
+
+ 4
|
|
1626
|
+
+ 4 + 9
|
|
1627
|
+
+ 4 + srcHandle.length
|
|
1628
|
+
+ 8
|
|
1629
|
+
+ 8
|
|
1630
|
+
+ 4 + dstHandle.length
|
|
1631
|
+
+ 8
|
|
1632
|
+
);
|
|
1633
|
+
|
|
1634
|
+
writeUInt32BE(buf, buf.length - 4, p);
|
|
1635
|
+
p += 4;
|
|
1636
|
+
|
|
1637
|
+
buf[p] = REQUEST.EXTENDED;
|
|
1638
|
+
++p;
|
|
1639
|
+
|
|
1640
|
+
const reqid = this._writeReqid = (this._writeReqid + 1) & MAX_REQID;
|
|
1641
|
+
writeUInt32BE(buf, reqid, p);
|
|
1642
|
+
p += 4;
|
|
1643
|
+
|
|
1644
|
+
writeUInt32BE(buf, 9, p);
|
|
1645
|
+
p += 4;
|
|
1646
|
+
buf.utf8Write('copy-data', p, 9);
|
|
1647
|
+
p += 9;
|
|
1648
|
+
|
|
1649
|
+
writeUInt32BE(buf, srcHandle.length, p);
|
|
1650
|
+
p += 4;
|
|
1651
|
+
buf.set(srcHandle, p);
|
|
1652
|
+
p += srcHandle.length;
|
|
1653
|
+
|
|
1654
|
+
for (let i = 7; i >= 0; --i) {
|
|
1655
|
+
buf[p + i] = srcOffset & 0xFF;
|
|
1656
|
+
srcOffset /= 256;
|
|
1657
|
+
}
|
|
1658
|
+
p += 8;
|
|
1659
|
+
|
|
1660
|
+
for (let i = 7; i >= 0; --i) {
|
|
1661
|
+
buf[p + i] = len & 0xFF;
|
|
1662
|
+
len /= 256;
|
|
1663
|
+
}
|
|
1664
|
+
p += 8;
|
|
1665
|
+
|
|
1666
|
+
writeUInt32BE(buf, dstHandle.length, p);
|
|
1667
|
+
p += 4;
|
|
1668
|
+
buf.set(dstHandle, p);
|
|
1669
|
+
p += dstHandle.length;
|
|
1670
|
+
|
|
1671
|
+
for (let i = 7; i >= 0; --i) {
|
|
1672
|
+
buf[p + i] = dstOffset & 0xFF;
|
|
1673
|
+
dstOffset /= 256;
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
this._requests[reqid] = { cb };
|
|
1677
|
+
|
|
1678
|
+
const isBuffered = sendOrBuffer(this, buf);
|
|
1679
|
+
if (this._debug) {
|
|
1680
|
+
const status = (isBuffered ? 'Buffered' : 'Sending');
|
|
1681
|
+
this._debug(`SFTP: Outbound: ${status} copy-data`);
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1599
1684
|
// ===========================================================================
|
|
1600
1685
|
// Server-specific ===========================================================
|
|
1601
1686
|
// ===========================================================================
|
|
@@ -1922,11 +2007,12 @@ function read_(self, handle, buf, off, len, position, cb, req_) {
|
|
|
1922
2007
|
return;
|
|
1923
2008
|
}
|
|
1924
2009
|
|
|
2010
|
+
nb = (nb || 0);
|
|
1925
2011
|
if (req.origOff === 0 && buf.length === req.nb)
|
|
1926
2012
|
data = buf;
|
|
1927
2013
|
else
|
|
1928
|
-
data = bufferSlice(buf, req.origOff, req.origOff + req.nb);
|
|
1929
|
-
cb(undefined, req.nb +
|
|
2014
|
+
data = bufferSlice(buf, req.origOff, req.origOff + req.nb + nb);
|
|
2015
|
+
cb(undefined, req.nb + nb, data, req.position);
|
|
1930
2016
|
},
|
|
1931
2017
|
buffer: undefined,
|
|
1932
2018
|
});
|
|
@@ -2416,7 +2502,8 @@ function tryWritePayload(sftp, payload) {
|
|
|
2416
2502
|
return;
|
|
2417
2503
|
|
|
2418
2504
|
if (outgoing.window === 0) {
|
|
2419
|
-
sftp._waitWindow = true;
|
|
2505
|
+
sftp._waitWindow = true;
|
|
2506
|
+
sftp._chunkcb = drainBuffer;
|
|
2420
2507
|
return payload;
|
|
2421
2508
|
}
|
|
2422
2509
|
|
|
@@ -3386,7 +3473,7 @@ function ReadStream(sftp, path, options) {
|
|
|
3386
3473
|
this.autoClose = options.autoClose === undefined ? true : options.autoClose;
|
|
3387
3474
|
this.pos = 0;
|
|
3388
3475
|
this.bytesRead = 0;
|
|
3389
|
-
this.
|
|
3476
|
+
this.isClosed = false;
|
|
3390
3477
|
|
|
3391
3478
|
this.handle = options.handle === undefined ? null : options.handle;
|
|
3392
3479
|
this.sftp = sftp;
|
|
@@ -3538,7 +3625,7 @@ function closeStream(stream, cb, err) {
|
|
|
3538
3625
|
function onclose(er) {
|
|
3539
3626
|
er = er || err;
|
|
3540
3627
|
cb(er);
|
|
3541
|
-
stream.
|
|
3628
|
+
stream.isClosed = true;
|
|
3542
3629
|
if (!er)
|
|
3543
3630
|
stream.emit('close');
|
|
3544
3631
|
}
|
|
@@ -3581,7 +3668,7 @@ function WriteStream(sftp, path, options) {
|
|
|
3581
3668
|
this.autoClose = options.autoClose === undefined ? true : options.autoClose;
|
|
3582
3669
|
this.pos = 0;
|
|
3583
3670
|
this.bytesWritten = 0;
|
|
3584
|
-
this.
|
|
3671
|
+
this.isClosed = false;
|
|
3585
3672
|
|
|
3586
3673
|
this.handle = options.handle === undefined ? null : options.handle;
|
|
3587
3674
|
this.sftp = sftp;
|
|
@@ -3741,7 +3828,7 @@ if (typeof WritableStream.prototype.destroy !== 'function')
|
|
|
3741
3828
|
WriteStream.prototype._destroy = ReadStream.prototype._destroy;
|
|
3742
3829
|
WriteStream.prototype.close = function(cb) {
|
|
3743
3830
|
if (cb) {
|
|
3744
|
-
if (this.
|
|
3831
|
+
if (this.isClosed) {
|
|
3745
3832
|
process.nextTick(cb);
|
|
3746
3833
|
return;
|
|
3747
3834
|
}
|
|
@@ -1,10 +1,20 @@
|
|
|
1
|
+
#if defined(__GNUC__) && __GNUC__ >= 8
|
|
2
|
+
#define DISABLE_WCAST_FUNCTION_TYPE _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wcast-function-type\"")
|
|
3
|
+
#define DISABLE_WCAST_FUNCTION_TYPE_END _Pragma("GCC diagnostic pop")
|
|
4
|
+
#else
|
|
5
|
+
#define DISABLE_WCAST_FUNCTION_TYPE
|
|
6
|
+
#define DISABLE_WCAST_FUNCTION_TYPE_END
|
|
7
|
+
#endif
|
|
8
|
+
|
|
1
9
|
#include <stdio.h>
|
|
2
10
|
#include <string.h>
|
|
3
11
|
#include <assert.h>
|
|
4
12
|
|
|
5
13
|
#include <node.h>
|
|
6
14
|
#include <node_buffer.h>
|
|
15
|
+
DISABLE_WCAST_FUNCTION_TYPE
|
|
7
16
|
#include <nan.h>
|
|
17
|
+
DISABLE_WCAST_FUNCTION_TYPE_END
|
|
8
18
|
|
|
9
19
|
#if NODE_MAJOR_VERSION >= 17
|
|
10
20
|
# include <openssl/configuration.h>
|
|
@@ -252,6 +262,8 @@ out:
|
|
|
252
262
|
|
|
253
263
|
// Poly1305 over ciphertext
|
|
254
264
|
#if REAL_OPENSSL_MAJOR >= 3
|
|
265
|
+
// TODO: check if dup()'ing a "base" context instead of calling init() with
|
|
266
|
+
// the key each time is faster
|
|
255
267
|
if (EVP_MAC_init(mac_ctx_, polykey, sizeof(polykey), nullptr) != 1
|
|
256
268
|
|| EVP_MAC_update(mac_ctx_, packet, data_len) != 1
|
|
257
269
|
|| EVP_MAC_final(mac_ctx_, packet + data_len, &sig_len, sig_len) != 1) {
|
|
@@ -452,11 +464,6 @@ class AESGCMCipher : public ObjectWrap {
|
|
|
452
464
|
goto out;
|
|
453
465
|
}
|
|
454
466
|
|
|
455
|
-
//~ if (iv_len != static_cast<size_t>(ctx_iv_len(ctx_))) {
|
|
456
|
-
//~ r = kErrBadIVLen;
|
|
457
|
-
//~ goto out;
|
|
458
|
-
//~ }
|
|
459
|
-
|
|
460
467
|
if (key_len != static_cast<size_t>(ctx_key_len(ctx_))) {
|
|
461
468
|
if (!EVP_CIPHER_CTX_set_key_length(ctx_, key_len)) {
|
|
462
469
|
r = kErrBadKeyLen;
|
|
@@ -654,7 +661,12 @@ class GenericCipher : public ObjectWrap {
|
|
|
654
661
|
private:
|
|
655
662
|
explicit GenericCipher()
|
|
656
663
|
: ctx_(nullptr),
|
|
664
|
+
#if REAL_OPENSSL_MAJOR >= 3
|
|
665
|
+
mac_(nullptr),
|
|
666
|
+
mac_ctx_base_(nullptr),
|
|
667
|
+
#else
|
|
657
668
|
ctx_hmac_(nullptr),
|
|
669
|
+
#endif
|
|
658
670
|
hmac_len_(0),
|
|
659
671
|
is_etm_(0) {}
|
|
660
672
|
|
|
@@ -667,10 +679,21 @@ class GenericCipher : public ObjectWrap {
|
|
|
667
679
|
EVP_CIPHER_CTX_free(ctx_);
|
|
668
680
|
ctx_ = nullptr;
|
|
669
681
|
}
|
|
682
|
+
#if REAL_OPENSSL_MAJOR >= 3
|
|
683
|
+
if (mac_ctx_base_) {
|
|
684
|
+
EVP_MAC_CTX_free(mac_ctx_base_);
|
|
685
|
+
mac_ctx_base_ = nullptr;
|
|
686
|
+
}
|
|
687
|
+
if (mac_) {
|
|
688
|
+
EVP_MAC_free(mac_);
|
|
689
|
+
mac_ = nullptr;
|
|
690
|
+
}
|
|
691
|
+
#else
|
|
670
692
|
if (ctx_hmac_) {
|
|
671
693
|
HMAC_CTX_free(ctx_hmac_);
|
|
672
694
|
ctx_hmac_ = nullptr;
|
|
673
695
|
}
|
|
696
|
+
#endif
|
|
674
697
|
}
|
|
675
698
|
|
|
676
699
|
ErrorType init(const char* name,
|
|
@@ -684,7 +707,11 @@ class GenericCipher : public ObjectWrap {
|
|
|
684
707
|
int is_etm) {
|
|
685
708
|
ErrorType r = kErrNone;
|
|
686
709
|
|
|
710
|
+
#if REAL_OPENSSL_MAJOR >= 3
|
|
711
|
+
OSSL_PARAM params[2];
|
|
712
|
+
#else
|
|
687
713
|
const EVP_MD* md;
|
|
714
|
+
#endif
|
|
688
715
|
const EVP_CIPHER* const cipher = EVP_get_cipherbyname(name);
|
|
689
716
|
if (cipher == nullptr) {
|
|
690
717
|
r = kErrOpenSSL;
|
|
@@ -742,6 +769,28 @@ class GenericCipher : public ObjectWrap {
|
|
|
742
769
|
}
|
|
743
770
|
}
|
|
744
771
|
|
|
772
|
+
#if REAL_OPENSSL_MAJOR >= 3
|
|
773
|
+
if ((mac_ = EVP_MAC_fetch(nullptr,
|
|
774
|
+
"HMAC",
|
|
775
|
+
"provider=default")) == nullptr) {
|
|
776
|
+
r = kErrOpenSSL;
|
|
777
|
+
goto out;
|
|
778
|
+
}
|
|
779
|
+
if ((mac_ctx_base_ = EVP_MAC_CTX_new(mac_)) == nullptr) {
|
|
780
|
+
r = kErrOpenSSL;
|
|
781
|
+
goto out;
|
|
782
|
+
}
|
|
783
|
+
params[0] = OSSL_PARAM_construct_utf8_string("digest",
|
|
784
|
+
const_cast<char*>(hmac_name),
|
|
785
|
+
0);
|
|
786
|
+
params[1] = OSSL_PARAM_END;
|
|
787
|
+
if (EVP_MAC_init(mac_ctx_base_, hmac_key, hmac_key_len, params) != 1) {
|
|
788
|
+
EVP_MAC_CTX_free(mac_ctx_base_);
|
|
789
|
+
r = kErrOpenSSL;
|
|
790
|
+
goto out;
|
|
791
|
+
}
|
|
792
|
+
hmac_len_ = EVP_MAC_CTX_get_mac_size(mac_ctx_base_);
|
|
793
|
+
#else
|
|
745
794
|
md = EVP_get_digestbyname(hmac_name);
|
|
746
795
|
if (md == nullptr) {
|
|
747
796
|
r = kErrBadHMACName;
|
|
@@ -755,6 +804,7 @@ class GenericCipher : public ObjectWrap {
|
|
|
755
804
|
}
|
|
756
805
|
|
|
757
806
|
hmac_len_ = HMAC_size(ctx_hmac_);
|
|
807
|
+
#endif
|
|
758
808
|
is_etm_ = is_etm;
|
|
759
809
|
|
|
760
810
|
out:
|
|
@@ -792,39 +842,51 @@ out:
|
|
|
792
842
|
r = kErrPartialEncrypt;
|
|
793
843
|
goto out;
|
|
794
844
|
}
|
|
845
|
+
}
|
|
795
846
|
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
}
|
|
806
|
-
if (outlen != hmac_len_) {
|
|
807
|
-
r = kErrBadHMACLen;
|
|
808
|
-
goto out;
|
|
809
|
-
}
|
|
847
|
+
// Calculate HMAC
|
|
848
|
+
{
|
|
849
|
+
#if REAL_OPENSSL_MAJOR >= 3
|
|
850
|
+
size_t outlen = hmac_len_;
|
|
851
|
+
|
|
852
|
+
EVP_MAC_CTX* mac_ctx = EVP_MAC_CTX_dup(mac_ctx_base_);
|
|
853
|
+
if (mac_ctx == nullptr) {
|
|
854
|
+
r = kErrOpenSSL;
|
|
855
|
+
goto out;
|
|
810
856
|
}
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
857
|
+
if (EVP_MAC_update(mac_ctx, seqbuf, sizeof(seqbuf)) != 1
|
|
858
|
+
|| EVP_MAC_update(mac_ctx, packet, data_len) != 1
|
|
859
|
+
|| EVP_MAC_final(mac_ctx,
|
|
860
|
+
packet + data_len,
|
|
861
|
+
reinterpret_cast<size_t*>(&outlen),
|
|
862
|
+
outlen) != 1) {
|
|
863
|
+
EVP_MAC_CTX_free(mac_ctx);
|
|
864
|
+
r = kErrOpenSSL;
|
|
865
|
+
goto out;
|
|
866
|
+
}
|
|
867
|
+
if (outlen != hmac_len_) {
|
|
868
|
+
EVP_MAC_CTX_free(mac_ctx);
|
|
869
|
+
r = kErrBadHMACLen;
|
|
870
|
+
goto out;
|
|
871
|
+
}
|
|
872
|
+
EVP_MAC_CTX_free(mac_ctx);
|
|
873
|
+
#else
|
|
874
|
+
unsigned int outlen = hmac_len_;
|
|
875
|
+
if (HMAC_Init_ex(ctx_hmac_, nullptr, 0, nullptr, nullptr) != 1
|
|
876
|
+
|| HMAC_Update(ctx_hmac_, seqbuf, sizeof(seqbuf)) != 1
|
|
877
|
+
|| HMAC_Update(ctx_hmac_, packet, data_len) != 1
|
|
878
|
+
|| HMAC_Final(ctx_hmac_, packet + data_len, &outlen) != 1) {
|
|
879
|
+
r = kErrOpenSSL;
|
|
880
|
+
goto out;
|
|
826
881
|
}
|
|
882
|
+
if (outlen != hmac_len_) {
|
|
883
|
+
r = kErrBadHMACLen;
|
|
884
|
+
goto out;
|
|
885
|
+
}
|
|
886
|
+
#endif
|
|
887
|
+
}
|
|
827
888
|
|
|
889
|
+
if (!is_etm_) {
|
|
828
890
|
// Encrypt packet
|
|
829
891
|
if (EVP_EncryptUpdate(ctx_,
|
|
830
892
|
packet,
|
|
@@ -958,8 +1020,14 @@ out:
|
|
|
958
1020
|
}
|
|
959
1021
|
|
|
960
1022
|
EVP_CIPHER_CTX* ctx_;
|
|
1023
|
+
#if REAL_OPENSSL_MAJOR >= 3
|
|
1024
|
+
EVP_MAC* mac_;
|
|
1025
|
+
EVP_MAC_CTX* mac_ctx_base_;
|
|
1026
|
+
size_t hmac_len_;
|
|
1027
|
+
#else
|
|
961
1028
|
HMAC_CTX* ctx_hmac_;
|
|
962
1029
|
unsigned int hmac_len_;
|
|
1030
|
+
#endif
|
|
963
1031
|
int is_etm_;
|
|
964
1032
|
};
|
|
965
1033
|
|
|
@@ -1163,6 +1231,8 @@ out:
|
|
|
1163
1231
|
|
|
1164
1232
|
// Poly1305 over ciphertext
|
|
1165
1233
|
#if REAL_OPENSSL_MAJOR >= 3
|
|
1234
|
+
// TODO: check if dup()'ing a "base" context instead of calling init() with
|
|
1235
|
+
// the key each time is faster
|
|
1166
1236
|
if (EVP_MAC_init(mac_ctx_, polykey, sizeof(polykey), nullptr) != 1
|
|
1167
1237
|
|| EVP_MAC_update(mac_ctx_, length_bytes, sizeof(length_bytes)) != 1
|
|
1168
1238
|
|| EVP_MAC_update(mac_ctx_, packet, packet_len) != 1
|
|
@@ -1448,11 +1518,6 @@ class AESGCMDecipher : public ObjectWrap {
|
|
|
1448
1518
|
goto out;
|
|
1449
1519
|
}
|
|
1450
1520
|
|
|
1451
|
-
//~ if (iv_len != static_cast<size_t>(ctx_iv_len(ctx_))) {
|
|
1452
|
-
//~ r = kErrBadIVLen;
|
|
1453
|
-
//~ goto out;
|
|
1454
|
-
//~ }
|
|
1455
|
-
|
|
1456
1521
|
if (key_len != static_cast<size_t>(ctx_key_len(ctx_))) {
|
|
1457
1522
|
if (!EVP_CIPHER_CTX_set_key_length(ctx_, key_len)) {
|
|
1458
1523
|
r = kErrBadKeyLen;
|
|
@@ -1661,7 +1726,12 @@ class GenericDecipher : public ObjectWrap {
|
|
|
1661
1726
|
private:
|
|
1662
1727
|
explicit GenericDecipher()
|
|
1663
1728
|
: ctx_(nullptr),
|
|
1729
|
+
#if REAL_OPENSSL_MAJOR >= 3
|
|
1730
|
+
mac_(nullptr),
|
|
1731
|
+
mac_ctx_base_(nullptr),
|
|
1732
|
+
#else
|
|
1664
1733
|
ctx_hmac_(nullptr),
|
|
1734
|
+
#endif
|
|
1665
1735
|
hmac_len_(0),
|
|
1666
1736
|
is_etm_(0) {}
|
|
1667
1737
|
|
|
@@ -1674,10 +1744,21 @@ class GenericDecipher : public ObjectWrap {
|
|
|
1674
1744
|
EVP_CIPHER_CTX_free(ctx_);
|
|
1675
1745
|
ctx_ = nullptr;
|
|
1676
1746
|
}
|
|
1747
|
+
#if REAL_OPENSSL_MAJOR >= 3
|
|
1748
|
+
if (mac_ctx_base_) {
|
|
1749
|
+
EVP_MAC_CTX_free(mac_ctx_base_);
|
|
1750
|
+
mac_ctx_base_ = nullptr;
|
|
1751
|
+
}
|
|
1752
|
+
if (mac_) {
|
|
1753
|
+
EVP_MAC_free(mac_);
|
|
1754
|
+
mac_ = nullptr;
|
|
1755
|
+
}
|
|
1756
|
+
#else
|
|
1677
1757
|
if (ctx_hmac_) {
|
|
1678
1758
|
HMAC_CTX_free(ctx_hmac_);
|
|
1679
1759
|
ctx_hmac_ = nullptr;
|
|
1680
1760
|
}
|
|
1761
|
+
#endif
|
|
1681
1762
|
}
|
|
1682
1763
|
|
|
1683
1764
|
ErrorType init(const char* name,
|
|
@@ -1692,7 +1773,11 @@ class GenericDecipher : public ObjectWrap {
|
|
|
1692
1773
|
size_t hmac_actual_len) {
|
|
1693
1774
|
ErrorType r = kErrNone;
|
|
1694
1775
|
|
|
1776
|
+
#if REAL_OPENSSL_MAJOR >= 3
|
|
1777
|
+
OSSL_PARAM params[2];
|
|
1778
|
+
#else
|
|
1695
1779
|
const EVP_MD* md;
|
|
1780
|
+
#endif
|
|
1696
1781
|
const EVP_CIPHER* const cipher = EVP_get_cipherbyname(name);
|
|
1697
1782
|
if (cipher == nullptr) {
|
|
1698
1783
|
r = kErrOpenSSL;
|
|
@@ -1750,6 +1835,28 @@ class GenericDecipher : public ObjectWrap {
|
|
|
1750
1835
|
}
|
|
1751
1836
|
}
|
|
1752
1837
|
|
|
1838
|
+
#if REAL_OPENSSL_MAJOR >= 3
|
|
1839
|
+
if ((mac_ = EVP_MAC_fetch(nullptr,
|
|
1840
|
+
"HMAC",
|
|
1841
|
+
"provider=default")) == nullptr) {
|
|
1842
|
+
r = kErrOpenSSL;
|
|
1843
|
+
goto out;
|
|
1844
|
+
}
|
|
1845
|
+
if ((mac_ctx_base_ = EVP_MAC_CTX_new(mac_)) == nullptr) {
|
|
1846
|
+
r = kErrOpenSSL;
|
|
1847
|
+
goto out;
|
|
1848
|
+
}
|
|
1849
|
+
params[0] = OSSL_PARAM_construct_utf8_string("digest",
|
|
1850
|
+
const_cast<char*>(hmac_name),
|
|
1851
|
+
0);
|
|
1852
|
+
params[1] = OSSL_PARAM_END;
|
|
1853
|
+
if (EVP_MAC_init(mac_ctx_base_, hmac_key, hmac_key_len, params) != 1) {
|
|
1854
|
+
EVP_MAC_CTX_free(mac_ctx_base_);
|
|
1855
|
+
r = kErrOpenSSL;
|
|
1856
|
+
goto out;
|
|
1857
|
+
}
|
|
1858
|
+
hmac_len_ = EVP_MAC_CTX_get_mac_size(mac_ctx_base_);
|
|
1859
|
+
#else
|
|
1753
1860
|
md = EVP_get_digestbyname(hmac_name);
|
|
1754
1861
|
if (md == nullptr) {
|
|
1755
1862
|
r = kErrBadHMACName;
|
|
@@ -1763,6 +1870,7 @@ class GenericDecipher : public ObjectWrap {
|
|
|
1763
1870
|
}
|
|
1764
1871
|
|
|
1765
1872
|
hmac_len_ = HMAC_size(ctx_hmac_);
|
|
1873
|
+
#endif
|
|
1766
1874
|
hmac_actual_len_ = hmac_actual_len;
|
|
1767
1875
|
is_etm_ = is_etm;
|
|
1768
1876
|
#if REAL_OPENSSL_MAJOR >= 3
|
|
@@ -1825,47 +1933,7 @@ out:
|
|
|
1825
1933
|
((uint8_t*)(seqbuf))[2] = (seqno >> 8) & 0xff;
|
|
1826
1934
|
((uint8_t*)(seqbuf))[3] = seqno & 0xff;
|
|
1827
1935
|
|
|
1828
|
-
if (is_etm_) {
|
|
1829
|
-
// `first_block` for ETM should just be the unencrypted packet length
|
|
1830
|
-
if (first_block_len != 4) {
|
|
1831
|
-
r = kErrBadBlockLen;
|
|
1832
|
-
goto out;
|
|
1833
|
-
}
|
|
1834
|
-
|
|
1835
|
-
// HMAC over unencrypted packet length and ciphertext
|
|
1836
|
-
{
|
|
1837
|
-
unsigned int outlen = hmac_len_;
|
|
1838
|
-
if (HMAC_Init_ex(ctx_hmac_, nullptr, 0, nullptr, nullptr) != 1
|
|
1839
|
-
|| HMAC_Update(ctx_hmac_, seqbuf, sizeof(seqbuf)) != 1
|
|
1840
|
-
|| HMAC_Update(ctx_hmac_, first_block, 4) != 1
|
|
1841
|
-
|| HMAC_Update(ctx_hmac_, packet, packet_len) != 1
|
|
1842
|
-
|| HMAC_Final(ctx_hmac_, calc_mac, &outlen) != 1) {
|
|
1843
|
-
r = kErrOpenSSL;
|
|
1844
|
-
goto out;
|
|
1845
|
-
}
|
|
1846
|
-
|
|
1847
|
-
if (outlen != hmac_len_ || mac_len != hmac_len_) {
|
|
1848
|
-
r = kErrBadHMACLen;
|
|
1849
|
-
goto out;
|
|
1850
|
-
}
|
|
1851
|
-
|
|
1852
|
-
// Compare MACs
|
|
1853
|
-
if (CRYPTO_memcmp(mac, calc_mac, hmac_len_)) {
|
|
1854
|
-
r = kErrInvalidMAC;
|
|
1855
|
-
goto out;
|
|
1856
|
-
}
|
|
1857
|
-
}
|
|
1858
|
-
|
|
1859
|
-
// Decrypt packet
|
|
1860
|
-
if (EVP_DecryptUpdate(ctx_, packet, &outlen, packet, packet_len) != 1) {
|
|
1861
|
-
r = kErrOpenSSL;
|
|
1862
|
-
goto out;
|
|
1863
|
-
}
|
|
1864
|
-
if (static_cast<size_t>(outlen) != packet_len) {
|
|
1865
|
-
r = kErrPartialDecrypt;
|
|
1866
|
-
goto out;
|
|
1867
|
-
}
|
|
1868
|
-
} else {
|
|
1936
|
+
if (!is_etm_) {
|
|
1869
1937
|
// `first_block` for non-ETM should be a completely decrypted first block
|
|
1870
1938
|
if (!is_stream_ && first_block_len != block_size_) {
|
|
1871
1939
|
r = kErrBadBlockLen;
|
|
@@ -1886,29 +1954,73 @@ out:
|
|
|
1886
1954
|
r = kErrPartialDecrypt;
|
|
1887
1955
|
goto out;
|
|
1888
1956
|
}
|
|
1957
|
+
}
|
|
1958
|
+
|
|
1959
|
+
// Calculate and compare HMAC
|
|
1960
|
+
{
|
|
1961
|
+
#if REAL_OPENSSL_MAJOR >= 3
|
|
1962
|
+
size_t outlen = hmac_len_;
|
|
1889
1963
|
|
|
1890
|
-
|
|
1891
|
-
{
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1964
|
+
EVP_MAC_CTX* mac_ctx = EVP_MAC_CTX_dup(mac_ctx_base_);
|
|
1965
|
+
if (mac_ctx == nullptr) {
|
|
1966
|
+
r = kErrOpenSSL;
|
|
1967
|
+
goto out;
|
|
1968
|
+
}
|
|
1969
|
+
if (EVP_MAC_update(mac_ctx, seqbuf, sizeof(seqbuf)) != 1
|
|
1970
|
+
|| EVP_MAC_update(mac_ctx, first_block, 4) != 1
|
|
1971
|
+
|| EVP_MAC_update(mac_ctx, packet, packet_len) != 1
|
|
1972
|
+
|| EVP_MAC_final(mac_ctx,
|
|
1973
|
+
calc_mac,
|
|
1974
|
+
&outlen,
|
|
1975
|
+
outlen) != 1) {
|
|
1976
|
+
EVP_MAC_CTX_free(mac_ctx);
|
|
1977
|
+
r = kErrOpenSSL;
|
|
1978
|
+
goto out;
|
|
1979
|
+
}
|
|
1980
|
+
if (outlen != hmac_len_ || mac_len != hmac_actual_len_) {
|
|
1981
|
+
EVP_MAC_CTX_free(mac_ctx);
|
|
1982
|
+
r = kErrBadHMACLen;
|
|
1983
|
+
goto out;
|
|
1984
|
+
}
|
|
1985
|
+
EVP_MAC_CTX_free(mac_ctx);
|
|
1986
|
+
#else
|
|
1987
|
+
unsigned int outlen = hmac_len_;
|
|
1988
|
+
if (HMAC_Init_ex(ctx_hmac_, nullptr, 0, nullptr, nullptr) != 1
|
|
1989
|
+
|| HMAC_Update(ctx_hmac_, seqbuf, sizeof(seqbuf)) != 1
|
|
1990
|
+
|| HMAC_Update(ctx_hmac_, first_block, 4) != 1
|
|
1991
|
+
|| HMAC_Update(ctx_hmac_, packet, packet_len) != 1
|
|
1992
|
+
|| HMAC_Final(ctx_hmac_, calc_mac, &outlen) != 1) {
|
|
1993
|
+
r = kErrOpenSSL;
|
|
1994
|
+
goto out;
|
|
1995
|
+
}
|
|
1996
|
+
if (outlen != hmac_len_ || mac_len != hmac_actual_len_) {
|
|
1997
|
+
r = kErrBadHMACLen;
|
|
1998
|
+
goto out;
|
|
1999
|
+
}
|
|
2000
|
+
#endif
|
|
2001
|
+
|
|
2002
|
+
// Compare MACs
|
|
2003
|
+
if (CRYPTO_memcmp(mac, calc_mac, hmac_actual_len_)) {
|
|
2004
|
+
r = kErrInvalidMAC;
|
|
2005
|
+
goto out;
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
if (is_etm_) {
|
|
2010
|
+
// `first_block` for ETM should just be the unencrypted packet length
|
|
2011
|
+
if (first_block_len != 4) {
|
|
2012
|
+
r = kErrBadBlockLen;
|
|
2013
|
+
goto out;
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
// Decrypt packet
|
|
2017
|
+
if (EVP_DecryptUpdate(ctx_, packet, &outlen, packet, packet_len) != 1) {
|
|
2018
|
+
r = kErrOpenSSL;
|
|
2019
|
+
goto out;
|
|
2020
|
+
}
|
|
2021
|
+
if (static_cast<size_t>(outlen) != packet_len) {
|
|
2022
|
+
r = kErrPartialDecrypt;
|
|
2023
|
+
goto out;
|
|
1912
2024
|
}
|
|
1913
2025
|
}
|
|
1914
2026
|
|
|
@@ -2077,8 +2189,14 @@ out:
|
|
|
2077
2189
|
}
|
|
2078
2190
|
|
|
2079
2191
|
EVP_CIPHER_CTX* ctx_;
|
|
2192
|
+
#if REAL_OPENSSL_MAJOR >= 3
|
|
2193
|
+
EVP_MAC* mac_;
|
|
2194
|
+
EVP_MAC_CTX* mac_ctx_base_;
|
|
2195
|
+
size_t hmac_len_;
|
|
2196
|
+
#else
|
|
2080
2197
|
HMAC_CTX* ctx_hmac_;
|
|
2081
2198
|
unsigned int hmac_len_;
|
|
2199
|
+
#endif
|
|
2082
2200
|
unsigned int hmac_actual_len_;
|
|
2083
2201
|
uint8_t is_etm_;
|
|
2084
2202
|
uint8_t is_stream_;
|
|
@@ -2145,4 +2263,6 @@ NAN_MODULE_INIT(init) {
|
|
|
2145
2263
|
GenericDecipher::Init(target);
|
|
2146
2264
|
}
|
|
2147
2265
|
|
|
2266
|
+
DISABLE_WCAST_FUNCTION_TYPE
|
|
2148
2267
|
NODE_MODULE(sshcrypto, init)
|
|
2268
|
+
DISABLE_WCAST_FUNCTION_TYPE_END
|
package/package.json
CHANGED