libssh2

Форк
0
/
mbedtls.c 
1538 строк · 42.0 Кб
1
/* Copyright (C) Art <https://github.com/wildart>
2
 * All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms,
5
 * with or without modification, are permitted provided
6
 * that the following conditions are met:
7
 *
8
 *   Redistributions of source code must retain the above
9
 *   copyright notice, this list of conditions and the
10
 *   following disclaimer.
11
 *
12
 *   Redistributions in binary form must reproduce the above
13
 *   copyright notice, this list of conditions and the following
14
 *   disclaimer in the documentation and/or other materials
15
 *   provided with the distribution.
16
 *
17
 *   Neither the name of the copyright holder nor the names
18
 *   of any other contributors may be used to endorse or
19
 *   promote products derived from this software without
20
 *   specific prior written permission.
21
 *
22
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
34
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35
 * OF SUCH DAMAGE.
36
 *
37
 * SPDX-License-Identifier: BSD-3-Clause
38
 */
39

40
#ifdef LIBSSH2_CRYPTO_C /* Compile this via crypto.c */
41

42
#include <stdlib.h>
43

44
#if MBEDTLS_VERSION_NUMBER < 0x03000000
45
#define mbedtls_cipher_info_get_key_bitlen(c) (c->key_bitlen)
46
#define mbedtls_cipher_info_get_iv_size(c)    (c->iv_size)
47
#define mbedtls_rsa_get_len(rsa)              (rsa->len)
48

49
#define MBEDTLS_PRIVATE(m) m
50
#endif
51

52
/*******************************************************************/
53
/*
54
 * mbedTLS backend: Global context handles
55
 */
56

57
static mbedtls_entropy_context  _libssh2_mbedtls_entropy;
58
static mbedtls_ctr_drbg_context _libssh2_mbedtls_ctr_drbg;
59

60
/*******************************************************************/
61
/*
62
 * mbedTLS backend: Generic functions
63
 */
64

65
void
66
_libssh2_mbedtls_init(void)
67
{
68
    int ret;
69

70
    mbedtls_entropy_init(&_libssh2_mbedtls_entropy);
71
    mbedtls_ctr_drbg_init(&_libssh2_mbedtls_ctr_drbg);
72

73
    ret = mbedtls_ctr_drbg_seed(&_libssh2_mbedtls_ctr_drbg,
74
                                mbedtls_entropy_func,
75
                                &_libssh2_mbedtls_entropy, NULL, 0);
76
    if(ret)
77
        mbedtls_ctr_drbg_free(&_libssh2_mbedtls_ctr_drbg);
78
}
79

80
void
81
_libssh2_mbedtls_free(void)
82
{
83
    mbedtls_ctr_drbg_free(&_libssh2_mbedtls_ctr_drbg);
84
    mbedtls_entropy_free(&_libssh2_mbedtls_entropy);
85
}
86

87
int
88
_libssh2_mbedtls_random(unsigned char *buf, size_t len)
89
{
90
    int ret;
91
    ret = mbedtls_ctr_drbg_random(&_libssh2_mbedtls_ctr_drbg, buf, len);
92
    return ret == 0 ? 0 : -1;
93
}
94

95
static void
96
_libssh2_mbedtls_safe_free(void *buf, size_t len)
97
{
98
    if(!buf)
99
        return;
100

101
    if(len > 0)
102
        _libssh2_explicit_zero(buf, len);
103

104
    mbedtls_free(buf);
105
}
106

107
int
108
_libssh2_mbedtls_cipher_init(_libssh2_cipher_ctx *ctx,
109
                             _libssh2_cipher_type(algo),
110
                             unsigned char *iv,
111
                             unsigned char *secret,
112
                             int encrypt)
113
{
114
    const mbedtls_cipher_info_t *cipher_info;
115
    int ret, op;
116

117
    if(!ctx)
118
        return -1;
119

120
    op = encrypt == 0 ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT;
121

122
    cipher_info = mbedtls_cipher_info_from_type(algo);
123
    if(!cipher_info)
124
        return -1;
125

126
    mbedtls_cipher_init(ctx);
127
    ret = mbedtls_cipher_setup(ctx, cipher_info);
128
    if(!ret)
129
        ret = mbedtls_cipher_setkey(ctx,
130
                  secret,
131
                  (int)mbedtls_cipher_info_get_key_bitlen(cipher_info),
132
                  op);
133

134
    if(!ret)
135
        ret = mbedtls_cipher_set_iv(ctx, iv,
136
                  mbedtls_cipher_info_get_iv_size(cipher_info));
137

138
    return ret == 0 ? 0 : -1;
139
}
140

141
int
142
_libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx *ctx,
143
                              _libssh2_cipher_type(algo),
144
                              int encrypt,
145
                              unsigned char *block,
146
                              size_t blocklen, int firstlast)
147
{
148
    int ret;
149
    unsigned char *output;
150
    size_t osize, olen, finish_olen;
151

152
    (void)encrypt;
153
    (void)algo;
154
    (void)firstlast;
155

156
    osize = blocklen + mbedtls_cipher_get_block_size(ctx);
157

158
    output = (unsigned char *)mbedtls_calloc(osize, sizeof(char));
159
    if(output) {
160
        ret = mbedtls_cipher_reset(ctx);
161

162
        if(!ret)
163
            ret = mbedtls_cipher_update(ctx, block, blocklen, output, &olen);
164

165
        if(!ret)
166
            ret = mbedtls_cipher_finish(ctx, output + olen, &finish_olen);
167

168
        if(!ret) {
169
            olen += finish_olen;
170
            memcpy(block, output, olen);
171
        }
172

173
        _libssh2_mbedtls_safe_free(output, osize);
174
    }
175
    else
176
        ret = -1;
177

178
    return ret == 0 ? 0 : -1;
179
}
180

181
void
182
_libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx)
183
{
184
    mbedtls_cipher_free(ctx);
185
}
186

187

188
int
189
_libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx,
190
                           mbedtls_md_type_t mdtype,
191
                           const unsigned char *key, size_t keylen)
192
{
193
    const mbedtls_md_info_t *md_info;
194
    int ret, hmac;
195

196
    md_info = mbedtls_md_info_from_type(mdtype);
197
    if(!md_info)
198
        return 0;
199

200
    hmac = key ? 1 : 0;
201

202
    mbedtls_md_init(ctx);
203
    ret = mbedtls_md_setup(ctx, md_info, hmac);
204
    if(!ret) {
205
        if(hmac)
206
            ret = mbedtls_md_hmac_starts(ctx, key, keylen);
207
        else
208
            ret = mbedtls_md_starts(ctx);
209
    }
210

211
    return ret == 0 ? 1 : 0;
212
}
213

214
int
215
_libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash)
216
{
217
    int ret;
218

219
    ret = mbedtls_md_finish(ctx, hash);
220
    mbedtls_md_free(ctx);
221

222
    return ret == 0 ? 1 : 0;
223
}
224

225
int
226
_libssh2_mbedtls_hash(const unsigned char *data, size_t datalen,
227
                      mbedtls_md_type_t mdtype, unsigned char *hash)
228
{
229
    const mbedtls_md_info_t *md_info;
230
    int ret;
231

232
    md_info = mbedtls_md_info_from_type(mdtype);
233
    if(!md_info)
234
        return 0;
235

236
    ret = mbedtls_md(md_info, data, datalen, hash);
237

238
    return ret == 0 ? 0 : -1;
239
}
240

241
int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx)
242
{
243
    memset(ctx, 0, sizeof(*ctx));
244
    return 1;
245
}
246

247
#if LIBSSH2_MD5
248
int _libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
249
                           void *key, size_t keylen)
250
{
251
    return _libssh2_mbedtls_hash_init(ctx, MBEDTLS_MD_MD5, key, keylen);
252
}
253
#endif
254

255
#if LIBSSH2_HMAC_RIPEMD
256
int _libssh2_hmac_ripemd160_init(libssh2_hmac_ctx *ctx,
257
                                 void *key, size_t keylen)
258
{
259
    return _libssh2_mbedtls_hash_init(ctx, MBEDTLS_MD_RIPEMD160, key, keylen);
260
}
261
#endif
262

263
int _libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
264
                            void *key, size_t keylen)
265
{
266
    return _libssh2_mbedtls_hash_init(ctx, MBEDTLS_MD_SHA1, key, keylen);
267
}
268

269
int _libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
270
                              void *key, size_t keylen)
271
{
272
    return _libssh2_mbedtls_hash_init(ctx, MBEDTLS_MD_SHA256, key, keylen);
273
}
274

275
int _libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
276
                              void *key, size_t keylen)
277
{
278
    return _libssh2_mbedtls_hash_init(ctx, MBEDTLS_MD_SHA512, key, keylen);
279
}
280

281
int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
282
                         const void *data, size_t datalen)
283
{
284
    int ret = mbedtls_md_hmac_update(ctx, data, datalen);
285

286
    return ret == 0 ? 1 : 0;
287
}
288

289
int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *data)
290
{
291
    int ret = mbedtls_md_hmac_finish(ctx, data);
292

293
    return ret == 0 ? 1 : 0;
294
}
295

296
void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx)
297
{
298
    mbedtls_md_free(ctx);
299
}
300

301
/*******************************************************************/
302
/*
303
 * mbedTLS backend: BigNumber functions
304
 */
305

306
_libssh2_bn *
307
_libssh2_mbedtls_bignum_init(void)
308
{
309
    _libssh2_bn *bignum;
310

311
    bignum = (_libssh2_bn *)mbedtls_calloc(1, sizeof(_libssh2_bn));
312
    if(bignum) {
313
        mbedtls_mpi_init(bignum);
314
    }
315

316
    return bignum;
317
}
318

319
void
320
_libssh2_mbedtls_bignum_free(_libssh2_bn *bn)
321
{
322
    if(bn) {
323
        mbedtls_mpi_free(bn);
324
        mbedtls_free(bn);
325
    }
326
}
327

328
static int
329
_libssh2_mbedtls_bignum_random(_libssh2_bn *bn, int bits, int top, int bottom)
330
{
331
    size_t len;
332
    int err;
333
    size_t i;
334

335
    if(!bn || bits <= 0)
336
        return -1;
337

338
    len = (bits + 7) >> 3;
339
    err = mbedtls_mpi_fill_random(bn, len, mbedtls_ctr_drbg_random,
340
                                  &_libssh2_mbedtls_ctr_drbg);
341
    if(err)
342
        return -1;
343

344
    /* Zero unused bits above the most significant bit */
345
    for(i = len*8 - 1; (size_t)bits <= i; --i) {
346
        err = mbedtls_mpi_set_bit(bn, i, 0);
347
        if(err)
348
            return -1;
349
    }
350

351
    /* If `top` is -1, the most significant bit of the random number can be
352
       zero.  If top is 0, the most significant bit of the random number is
353
       set to 1, and if top is 1, the two most significant bits of the number
354
       will be set to 1, so that the product of two such random numbers will
355
       always have 2*bits length.
356
    */
357
    if(top >= 0) {
358
        for(i = 0; i <= (size_t)top; ++i) {
359
            err = mbedtls_mpi_set_bit(bn, bits-i-1, 1);
360
            if(err)
361
                return -1;
362
        }
363
    }
364

365
    /* make odd by setting first bit in least significant byte */
366
    if(bottom) {
367
        err = mbedtls_mpi_set_bit(bn, 0, 1);
368
        if(err)
369
            return -1;
370
    }
371

372
    return 0;
373
}
374

375

376
/*******************************************************************/
377
/*
378
 * mbedTLS backend: RSA functions
379
 */
380

381
int
382
_libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa,
383
                         const unsigned char *edata,
384
                         unsigned long elen,
385
                         const unsigned char *ndata,
386
                         unsigned long nlen,
387
                         const unsigned char *ddata,
388
                         unsigned long dlen,
389
                         const unsigned char *pdata,
390
                         unsigned long plen,
391
                         const unsigned char *qdata,
392
                         unsigned long qlen,
393
                         const unsigned char *e1data,
394
                         unsigned long e1len,
395
                         const unsigned char *e2data,
396
                         unsigned long e2len,
397
                         const unsigned char *coeffdata,
398
                         unsigned long coefflen)
399
{
400
    int ret;
401
    libssh2_rsa_ctx *ctx;
402

403
    ctx = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx));
404
    if(ctx) {
405
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
406
        mbedtls_rsa_init(ctx);
407
#else
408
        mbedtls_rsa_init(ctx, MBEDTLS_RSA_PKCS_V15, 0);
409
#endif
410
    }
411
    else
412
        return -1;
413

414
    /* !checksrc! disable ASSIGNWITHINCONDITION 1 */
415
    if((ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(E)),
416
                                      edata, elen)) ||
417
       (ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(N)),
418
                                      ndata, nlen))) {
419
        ret = -1;
420
    }
421

422
    if(!ret) {
423
        ctx->MBEDTLS_PRIVATE(len) =
424
            mbedtls_mpi_size(&(ctx->MBEDTLS_PRIVATE(N)));
425
    }
426

427
    if(!ret && ddata) {
428
        /* !checksrc! disable ASSIGNWITHINCONDITION 1 */
429
        if((ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(D)),
430
                                          ddata, dlen)) ||
431
           (ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(P)),
432
                                          pdata, plen)) ||
433
           (ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(Q)),
434
                                          qdata, qlen)) ||
435
           (ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(DP)),
436
                                          e1data, e1len)) ||
437
           (ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(DQ)),
438
                                          e2data, e2len)) ||
439
           (ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(QP)),
440
                                          coeffdata, coefflen))) {
441
            ret = -1;
442
        }
443
        ret = mbedtls_rsa_check_privkey(ctx);
444
    }
445
    else if(!ret) {
446
        ret = mbedtls_rsa_check_pubkey(ctx);
447
    }
448

449
    if(ret && ctx) {
450
        _libssh2_mbedtls_rsa_free(ctx);
451
        ctx = NULL;
452
    }
453
    *rsa = ctx;
454
    return ret;
455
}
456

457
int
458
_libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa,
459
                                 LIBSSH2_SESSION *session,
460
                                 const char *filename,
461
                                 const unsigned char *passphrase)
462
{
463
    int ret;
464
    mbedtls_pk_context pkey;
465
    mbedtls_rsa_context *pk_rsa;
466

467
    *rsa = (libssh2_rsa_ctx *) LIBSSH2_ALLOC(session, sizeof(libssh2_rsa_ctx));
468
    if(!*rsa)
469
        return -1;
470

471
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
472
    mbedtls_rsa_init(*rsa);
473
#else
474
    mbedtls_rsa_init(*rsa, MBEDTLS_RSA_PKCS_V15, 0);
475
#endif
476
    mbedtls_pk_init(&pkey);
477

478
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
479
    ret = mbedtls_pk_parse_keyfile(&pkey, filename, (char *)passphrase,
480
                                   mbedtls_ctr_drbg_random,
481
                                   &_libssh2_mbedtls_ctr_drbg);
482
#else
483
    ret = mbedtls_pk_parse_keyfile(&pkey, filename, (char *)passphrase);
484
#endif
485
    if(ret || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) {
486
        mbedtls_pk_free(&pkey);
487
        mbedtls_rsa_free(*rsa);
488
        LIBSSH2_FREE(session, *rsa);
489
        *rsa = NULL;
490
        return -1;
491
    }
492

493
    pk_rsa = mbedtls_pk_rsa(pkey);
494
    mbedtls_rsa_copy(*rsa, pk_rsa);
495
    mbedtls_pk_free(&pkey);
496

497
    return 0;
498
}
499

500
int
501
_libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa,
502
                                            LIBSSH2_SESSION *session,
503
                                            const char *filedata,
504
                                            size_t filedata_len,
505
                                            unsigned const char *passphrase)
506
{
507
    int ret;
508
    mbedtls_pk_context pkey;
509
    mbedtls_rsa_context *pk_rsa;
510
    void *filedata_nullterm;
511
    size_t pwd_len;
512

513
    *rsa = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx));
514
    if(!*rsa)
515
        return -1;
516

517
    /*
518
    mbedtls checks in "mbedtls/pkparse.c:1184" if "key[keylen - 1] != '\0'"
519
    private-key from memory will fail if the last byte is not a null byte
520
    */
521
    filedata_nullterm = mbedtls_calloc(filedata_len + 1, 1);
522
    if(!filedata_nullterm) {
523
        return -1;
524
    }
525
    memcpy(filedata_nullterm, filedata, filedata_len);
526

527
    mbedtls_pk_init(&pkey);
528

529
    pwd_len = passphrase ? strlen((const char *)passphrase) : 0;
530
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
531
    ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata_nullterm,
532
                               filedata_len + 1,
533
                               passphrase, pwd_len,
534
                               mbedtls_ctr_drbg_random,
535
                               &_libssh2_mbedtls_ctr_drbg);
536
#else
537
    ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata_nullterm,
538
                               filedata_len + 1,
539
                               passphrase, pwd_len);
540
#endif
541
    _libssh2_mbedtls_safe_free(filedata_nullterm, filedata_len);
542

543
    if(ret || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) {
544
        mbedtls_pk_free(&pkey);
545
        mbedtls_rsa_free(*rsa);
546
        LIBSSH2_FREE(session, *rsa);
547
        *rsa = NULL;
548
        return -1;
549
    }
550

551
    pk_rsa = mbedtls_pk_rsa(pkey);
552
    mbedtls_rsa_copy(*rsa, pk_rsa);
553
    mbedtls_pk_free(&pkey);
554

555
    return 0;
556
}
557

558
int
559
_libssh2_mbedtls_rsa_sha2_verify(libssh2_rsa_ctx * rsactx,
560
                                 size_t hash_len,
561
                                 const unsigned char *sig,
562
                                 size_t sig_len,
563
                                 const unsigned char *m,
564
                                 size_t m_len)
565
{
566
    int ret;
567
    int md_type;
568
    unsigned char *hash;
569

570
    if(sig_len < mbedtls_rsa_get_len(rsactx))
571
        return -1;
572

573
    hash = malloc(hash_len);
574
    if(!hash)
575
        return -1;
576

577
    if(hash_len == SHA_DIGEST_LENGTH) {
578
        md_type = MBEDTLS_MD_SHA1;
579
    }
580
    else if(hash_len == SHA256_DIGEST_LENGTH) {
581
        md_type = MBEDTLS_MD_SHA256;
582
    }
583
    else if(hash_len == SHA512_DIGEST_LENGTH) {
584
        md_type = MBEDTLS_MD_SHA512;
585
    }
586
    else{
587
        free(hash);
588
        return -1; /* unsupported digest */
589
    }
590
    ret = _libssh2_mbedtls_hash(m, m_len, md_type, hash);
591

592
    if(ret) {
593
        free(hash);
594
        return -1; /* failure */
595
    }
596

597
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
598
    ret = mbedtls_rsa_pkcs1_verify(rsactx,
599
                                   md_type, (unsigned int)hash_len,
600
                                   hash, sig);
601
#else
602
    ret = mbedtls_rsa_pkcs1_verify(rsactx, NULL, NULL, MBEDTLS_RSA_PUBLIC,
603
                                   md_type, (unsigned int)hash_len,
604
                                   hash, sig);
605
#endif
606
    free(hash);
607

608
    return (ret == 0) ? 0 : -1;
609
}
610

611
int
612
_libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx * rsactx,
613
                                 const unsigned char *sig,
614
                                 size_t sig_len,
615
                                 const unsigned char *m,
616
                                 size_t m_len)
617
{
618
    return _libssh2_mbedtls_rsa_sha2_verify(rsactx, SHA_DIGEST_LENGTH,
619
                                            sig, sig_len, m, m_len);
620
}
621

622
int
623
_libssh2_mbedtls_rsa_sha2_sign(LIBSSH2_SESSION *session,
624
                               libssh2_rsa_ctx *rsa,
625
                               const unsigned char *hash,
626
                               size_t hash_len,
627
                               unsigned char **signature,
628
                               size_t *signature_len)
629
{
630
    int ret;
631
    unsigned char *sig;
632
    size_t sig_len;
633
    int md_type;
634

635
    sig_len = mbedtls_rsa_get_len(rsa);
636
    sig = LIBSSH2_ALLOC(session, sig_len);
637
    if(!sig) {
638
        return -1;
639
    }
640
    ret = 0;
641
    if(hash_len == SHA_DIGEST_LENGTH) {
642
        md_type = MBEDTLS_MD_SHA1;
643
    }
644
    else if(hash_len == SHA256_DIGEST_LENGTH) {
645
        md_type = MBEDTLS_MD_SHA256;
646
    }
647
    else if(hash_len == SHA512_DIGEST_LENGTH) {
648
        md_type = MBEDTLS_MD_SHA512;
649
    }
650
    else {
651
        _libssh2_error(session, LIBSSH2_ERROR_PROTO,
652
                       "Unsupported hash digest length");
653
        ret = -1;
654
    }
655
    if(ret == 0) {
656
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
657
        ret = mbedtls_rsa_pkcs1_sign(rsa,
658
                                     mbedtls_ctr_drbg_random,
659
                                     &_libssh2_mbedtls_ctr_drbg,
660
                                     md_type, (unsigned int)hash_len,
661
                                     hash, sig);
662
#else
663
        ret = mbedtls_rsa_pkcs1_sign(rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE,
664
                                     md_type, (unsigned int)hash_len,
665
                                     hash, sig);
666
#endif
667
    }
668
    if(ret) {
669
        LIBSSH2_FREE(session, sig);
670
        return -1;
671
    }
672

673
    *signature = sig;
674
    *signature_len = sig_len;
675

676
    return (ret == 0) ? 0 : -1;
677
}
678

679
int
680
_libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION * session,
681
                               libssh2_rsa_ctx * rsactx,
682
                               const unsigned char *hash,
683
                               size_t hash_len,
684
                               unsigned char **signature,
685
                               size_t *signature_len)
686
{
687
    return _libssh2_mbedtls_rsa_sha2_sign(session, rsactx, hash, hash_len,
688
                                          signature, signature_len);
689
}
690

691
void
692
_libssh2_mbedtls_rsa_free(libssh2_rsa_ctx *ctx)
693
{
694
    mbedtls_rsa_free(ctx);
695
    mbedtls_free(ctx);
696
}
697

698
static unsigned char *
699
gen_publickey_from_rsa(LIBSSH2_SESSION *session,
700
                       mbedtls_rsa_context *rsa,
701
                       size_t *keylen)
702
{
703
    uint32_t e_bytes, n_bytes;
704
    uint32_t len;
705
    unsigned char *key;
706
    unsigned char *p;
707

708
    e_bytes = (uint32_t)mbedtls_mpi_size(&rsa->MBEDTLS_PRIVATE(E));
709
    n_bytes = (uint32_t)mbedtls_mpi_size(&rsa->MBEDTLS_PRIVATE(N));
710

711
    /* Key form is "ssh-rsa" + e + n. */
712
    len = 4 + 7 + 4 + e_bytes + 4 + n_bytes;
713

714
    key = LIBSSH2_ALLOC(session, len);
715
    if(!key) {
716
        return NULL;
717
    }
718

719
    /* Process key encoding. */
720
    p = key;
721

722
    _libssh2_htonu32(p, 7);  /* Key type. */
723
    p += 4;
724
    memcpy(p, "ssh-rsa", 7);
725
    p += 7;
726

727
    _libssh2_htonu32(p, e_bytes);
728
    p += 4;
729
    mbedtls_mpi_write_binary(&rsa->MBEDTLS_PRIVATE(E), p, e_bytes);
730

731
    _libssh2_htonu32(p, n_bytes);
732
    p += 4;
733
    mbedtls_mpi_write_binary(&rsa->MBEDTLS_PRIVATE(N), p, n_bytes);
734

735
    *keylen = (size_t)(p - key);
736
    return key;
737
}
738

739
static int
740
_libssh2_mbedtls_pub_priv_key(LIBSSH2_SESSION *session,
741
                              unsigned char **method,
742
                              size_t *method_len,
743
                              unsigned char **pubkeydata,
744
                              size_t *pubkeydata_len,
745
                              mbedtls_pk_context *pkey)
746
{
747
    unsigned char *key = NULL, *mth = NULL;
748
    size_t keylen = 0, mthlen = 0;
749
    int ret;
750
    mbedtls_rsa_context *rsa;
751

752
    if(mbedtls_pk_get_type(pkey) != MBEDTLS_PK_RSA) {
753
        mbedtls_pk_free(pkey);
754
        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
755
                              "Key type not supported");
756
    }
757

758
    /* write method */
759
    mthlen = 7;
760
    mth = LIBSSH2_ALLOC(session, mthlen);
761
    if(mth) {
762
        memcpy(mth, "ssh-rsa", mthlen);
763
    }
764
    else {
765
        ret = -1;
766
    }
767

768
    rsa = mbedtls_pk_rsa(*pkey);
769
    key = gen_publickey_from_rsa(session, rsa, &keylen);
770
    if(!key) {
771
        ret = -1;
772
    }
773

774
    /* write output */
775
    if(ret) {
776
        if(mth)
777
            LIBSSH2_FREE(session, mth);
778
        if(key)
779
            LIBSSH2_FREE(session, key);
780
    }
781
    else {
782
        *method = mth;
783
        *method_len = mthlen;
784
        *pubkeydata = key;
785
        *pubkeydata_len = keylen;
786
    }
787

788
    return ret;
789
}
790

791
int
792
_libssh2_mbedtls_pub_priv_keyfile(LIBSSH2_SESSION *session,
793
                                  unsigned char **method,
794
                                  size_t *method_len,
795
                                  unsigned char **pubkeydata,
796
                                  size_t *pubkeydata_len,
797
                                  const char *privatekey,
798
                                  const char *passphrase)
799
{
800
    mbedtls_pk_context pkey;
801
    char buf[1024];
802
    int ret;
803

804
    mbedtls_pk_init(&pkey);
805
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
806
    ret = mbedtls_pk_parse_keyfile(&pkey, privatekey, passphrase,
807
                                   mbedtls_ctr_drbg_random,
808
                                   &_libssh2_mbedtls_ctr_drbg);
809
#else
810
    ret = mbedtls_pk_parse_keyfile(&pkey, privatekey, passphrase);
811
#endif
812
    if(ret) {
813
        mbedtls_strerror(ret, (char *)buf, sizeof(buf));
814
        mbedtls_pk_free(&pkey);
815
        return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf);
816
    }
817

818
    ret = _libssh2_mbedtls_pub_priv_key(session, method, method_len,
819
                                        pubkeydata, pubkeydata_len, &pkey);
820

821
    mbedtls_pk_free(&pkey);
822

823
    return ret;
824
}
825

826
int
827
_libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
828
                                        unsigned char **method,
829
                                        size_t *method_len,
830
                                        unsigned char **pubkeydata,
831
                                        size_t *pubkeydata_len,
832
                                        const char *privatekeydata,
833
                                        size_t privatekeydata_len,
834
                                        const char *passphrase)
835
{
836
    mbedtls_pk_context pkey;
837
    char buf[1024];
838
    int ret;
839
    void *privatekeydata_nullterm;
840
    size_t pwd_len;
841

842
    /*
843
    mbedtls checks in "mbedtls/pkparse.c:1184" if "key[keylen - 1] != '\0'"
844
    private-key from memory will fail if the last byte is not a null byte
845
    */
846
    privatekeydata_nullterm = mbedtls_calloc(privatekeydata_len + 1, 1);
847
    if(!privatekeydata_nullterm) {
848
        return -1;
849
    }
850
    memcpy(privatekeydata_nullterm, privatekeydata, privatekeydata_len);
851

852
    mbedtls_pk_init(&pkey);
853

854
    pwd_len = passphrase ? strlen((const char *)passphrase) : 0;
855
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
856
    ret = mbedtls_pk_parse_key(&pkey,
857
                               (unsigned char *)privatekeydata_nullterm,
858
                               privatekeydata_len + 1,
859
                               (const unsigned char *)passphrase, pwd_len,
860
                               mbedtls_ctr_drbg_random,
861
                               &_libssh2_mbedtls_ctr_drbg);
862
#else
863
    ret = mbedtls_pk_parse_key(&pkey,
864
                               (unsigned char *)privatekeydata_nullterm,
865
                               privatekeydata_len + 1,
866
                               (const unsigned char *)passphrase, pwd_len);
867
#endif
868
    _libssh2_mbedtls_safe_free(privatekeydata_nullterm, privatekeydata_len);
869

870
    if(ret) {
871
        mbedtls_strerror(ret, (char *)buf, sizeof(buf));
872
        mbedtls_pk_free(&pkey);
873
        return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf);
874
    }
875

876
    ret = _libssh2_mbedtls_pub_priv_key(session, method, method_len,
877
                                        pubkeydata, pubkeydata_len, &pkey);
878

879
    mbedtls_pk_free(&pkey);
880

881
    return ret;
882
}
883

884
int
885
_libssh2_mbedtls_sk_pub_keyfilememory(LIBSSH2_SESSION *session,
886
                                      unsigned char **method,
887
                                      size_t *method_len,
888
                                      unsigned char **pubkeydata,
889
                                      size_t *pubkeydata_len,
890
                                      int *algorithm,
891
                                      unsigned char *flags,
892
                                      const char **application,
893
                                      const unsigned char **key_handle,
894
                                      size_t *handle_len,
895
                                      const char *privatekeydata,
896
                                      size_t privatekeydata_len,
897
                                      const char *passphrase)
898
{
899
    (void)method;
900
    (void)method_len;
901
    (void)pubkeydata;
902
    (void)pubkeydata_len;
903
    (void)algorithm;
904
    (void)flags;
905
    (void)application;
906
    (void)key_handle;
907
    (void)handle_len;
908
    (void)privatekeydata;
909
    (void)privatekeydata_len;
910
    (void)passphrase;
911

912
    return _libssh2_error(session, LIBSSH2_ERROR_FILE,
913
                    "Unable to extract public SK key from private key file: "
914
                    "Method unimplemented in mbedTLS backend");
915
}
916

917
void _libssh2_init_aes_ctr(void)
918
{
919
    /* no implementation */
920
}
921

922

923
/*******************************************************************/
924
/*
925
 * mbedTLS backend: Diffie-Hellman functions
926
 */
927

928
void
929
_libssh2_dh_init(_libssh2_dh_ctx *dhctx)
930
{
931
    *dhctx = _libssh2_mbedtls_bignum_init();    /* Random from client */
932
}
933

934
int
935
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
936
                     _libssh2_bn *g, _libssh2_bn *p, int group_order)
937
{
938
    /* Generate x and e */
939
    _libssh2_mbedtls_bignum_random(*dhctx, group_order * 8 - 1, 0, -1);
940
    mbedtls_mpi_exp_mod(public, g, *dhctx, p, NULL);
941
    return 0;
942
}
943

944
int
945
_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
946
                   _libssh2_bn *f, _libssh2_bn *p)
947
{
948
    /* Compute the shared secret */
949
    mbedtls_mpi_exp_mod(secret, f, *dhctx, p, NULL);
950
    return 0;
951
}
952

953
void
954
_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
955
{
956
    _libssh2_mbedtls_bignum_free(*dhctx);
957
    *dhctx = NULL;
958
}
959

960
#if LIBSSH2_ECDSA
961

962
/*******************************************************************/
963
/*
964
 * mbedTLS backend: ECDSA functions
965
 */
966

967
/*
968
 * _libssh2_ecdsa_create_key
969
 *
970
 * Creates a local private key based on input curve
971
 * and returns octal value and octal length
972
 *
973
 */
974

975
int
976
_libssh2_mbedtls_ecdsa_create_key(LIBSSH2_SESSION *session,
977
                                  _libssh2_ec_key **privkey,
978
                                  unsigned char **pubkey_oct,
979
                                  size_t *pubkey_oct_len,
980
                                  libssh2_curve_type curve)
981
{
982
    size_t plen = 0;
983

984
    *privkey = LIBSSH2_ALLOC(session, sizeof(mbedtls_ecp_keypair));
985

986
    if(!*privkey)
987
        goto failed;
988

989
    mbedtls_ecdsa_init(*privkey);
990

991
    if(mbedtls_ecdsa_genkey(*privkey, (mbedtls_ecp_group_id)curve,
992
                            mbedtls_ctr_drbg_random,
993
                            &_libssh2_mbedtls_ctr_drbg))
994
        goto failed;
995

996
    plen = 2 * mbedtls_mpi_size(&(*privkey)->MBEDTLS_PRIVATE(grp).P) + 1;
997
    *pubkey_oct = LIBSSH2_ALLOC(session, plen);
998

999
    if(!*pubkey_oct)
1000
        goto failed;
1001

1002
    if(mbedtls_ecp_point_write_binary(&(*privkey)->MBEDTLS_PRIVATE(grp),
1003
                                      &(*privkey)->MBEDTLS_PRIVATE(Q),
1004
                                      MBEDTLS_ECP_PF_UNCOMPRESSED,
1005
                                      pubkey_oct_len, *pubkey_oct, plen) == 0)
1006
        return 0;
1007

1008
failed:
1009

1010
    _libssh2_mbedtls_ecdsa_free(*privkey);
1011
    _libssh2_mbedtls_safe_free(*pubkey_oct, plen);
1012
    *privkey = NULL;
1013

1014
    return -1;
1015
}
1016

1017
/* _libssh2_ecdsa_curve_name_with_octal_new
1018
 *
1019
 * Creates a new public key given an octal string, length and type
1020
 *
1021
 */
1022

1023
int
1024
_libssh2_mbedtls_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx **ctx,
1025
                                                 const unsigned char *k,
1026
                                                 size_t k_len,
1027
                                                 libssh2_curve_type curve)
1028
{
1029
    *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
1030

1031
    if(!*ctx)
1032
        goto failed;
1033

1034
    mbedtls_ecdsa_init(*ctx);
1035

1036
    if(mbedtls_ecp_group_load(&(*ctx)->MBEDTLS_PRIVATE(grp),
1037
                              (mbedtls_ecp_group_id)curve))
1038
        goto failed;
1039

1040
    if(mbedtls_ecp_point_read_binary(&(*ctx)->MBEDTLS_PRIVATE(grp),
1041
                                     &(*ctx)->MBEDTLS_PRIVATE(Q),
1042
                                     k, k_len))
1043
        goto failed;
1044

1045
    if(mbedtls_ecp_check_pubkey(&(*ctx)->MBEDTLS_PRIVATE(grp),
1046
                                &(*ctx)->MBEDTLS_PRIVATE(Q)) == 0)
1047
        return 0;
1048

1049
failed:
1050

1051
    _libssh2_mbedtls_ecdsa_free(*ctx);
1052
    *ctx = NULL;
1053

1054
    return -1;
1055
}
1056

1057
/* _libssh2_ecdh_gen_k
1058
 *
1059
 * Computes the shared secret K given a local private key,
1060
 * remote public key and length
1061
 */
1062

1063
int
1064
_libssh2_mbedtls_ecdh_gen_k(_libssh2_bn **k,
1065
                            _libssh2_ec_key *privkey,
1066
                            const unsigned char *server_pubkey,
1067
                            size_t server_pubkey_len)
1068
{
1069
    mbedtls_ecp_point pubkey;
1070
    int rc = 0;
1071

1072
    if(!*k)
1073
        return -1;
1074

1075
    mbedtls_ecp_point_init(&pubkey);
1076

1077
    if(mbedtls_ecp_point_read_binary(&privkey->MBEDTLS_PRIVATE(grp),
1078
                                     &pubkey,
1079
                                     server_pubkey, server_pubkey_len)) {
1080
        rc = -1;
1081
        goto cleanup;
1082
    }
1083

1084
    if(mbedtls_ecdh_compute_shared(&privkey->MBEDTLS_PRIVATE(grp), *k,
1085
                                   &pubkey,
1086
                                   &privkey->MBEDTLS_PRIVATE(d),
1087
                                   mbedtls_ctr_drbg_random,
1088
                                   &_libssh2_mbedtls_ctr_drbg)) {
1089
        rc = -1;
1090
        goto cleanup;
1091
    }
1092

1093
    if(mbedtls_ecp_check_privkey(&privkey->MBEDTLS_PRIVATE(grp), *k))
1094
        rc = -1;
1095

1096
cleanup:
1097

1098
    mbedtls_ecp_point_free(&pubkey);
1099

1100
    return rc;
1101
}
1102

1103
#define LIBSSH2_MBEDTLS_ECDSA_VERIFY(digest_type)                           \
1104
    do {                                                                    \
1105
        unsigned char hsh[SHA##digest_type##_DIGEST_LENGTH];                \
1106
                                                                            \
1107
        if(libssh2_sha##digest_type(m, m_len, hsh) == 0) {                  \
1108
            rc = mbedtls_ecdsa_verify(&ctx->MBEDTLS_PRIVATE(grp), hsh,      \
1109
                                      SHA##digest_type##_DIGEST_LENGTH,     \
1110
                                      &ctx->MBEDTLS_PRIVATE(Q), &pr, &ps);  \
1111
        }                                                                   \
1112
    } while(0)
1113

1114
/* _libssh2_ecdsa_verify
1115
 *
1116
 * Verifies the ECDSA signature of a hashed message
1117
 *
1118
 */
1119

1120
int
1121
_libssh2_mbedtls_ecdsa_verify(libssh2_ecdsa_ctx *ctx,
1122
                              const unsigned char *r, size_t r_len,
1123
                              const unsigned char *s, size_t s_len,
1124
                              const unsigned char *m, size_t m_len)
1125
{
1126
    mbedtls_mpi pr, ps;
1127
    int rc = -1;
1128

1129
    mbedtls_mpi_init(&pr);
1130
    mbedtls_mpi_init(&ps);
1131

1132
    if(mbedtls_mpi_read_binary(&pr, r, r_len))
1133
        goto cleanup;
1134

1135
    if(mbedtls_mpi_read_binary(&ps, s, s_len))
1136
        goto cleanup;
1137

1138
    switch(_libssh2_ecdsa_get_curve_type(ctx)) {
1139
    case LIBSSH2_EC_CURVE_NISTP256:
1140
        LIBSSH2_MBEDTLS_ECDSA_VERIFY(256);
1141
        break;
1142
    case LIBSSH2_EC_CURVE_NISTP384:
1143
        LIBSSH2_MBEDTLS_ECDSA_VERIFY(384);
1144
        break;
1145
    case LIBSSH2_EC_CURVE_NISTP521:
1146
        LIBSSH2_MBEDTLS_ECDSA_VERIFY(512);
1147
        break;
1148
    default:
1149
        rc = -1;
1150
    }
1151

1152
cleanup:
1153

1154
    mbedtls_mpi_free(&pr);
1155
    mbedtls_mpi_free(&ps);
1156

1157
    return (rc == 0) ? 0 : -1;
1158
}
1159

1160
static int
1161
_libssh2_mbedtls_parse_eckey(libssh2_ecdsa_ctx **ctx,
1162
                             mbedtls_pk_context *pkey,
1163
                             LIBSSH2_SESSION *session,
1164
                             const unsigned char *data,
1165
                             size_t data_len,
1166
                             const unsigned char *pwd)
1167
{
1168
    size_t pwd_len;
1169

1170
    pwd_len = pwd ? strlen((const char *) pwd) : 0;
1171

1172
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
1173
    if(mbedtls_pk_parse_key(pkey, data, data_len, pwd, pwd_len,
1174
                            mbedtls_ctr_drbg_random,
1175
                            &_libssh2_mbedtls_ctr_drbg))
1176

1177
        goto failed;
1178
#else
1179
    if(mbedtls_pk_parse_key(pkey, data, data_len, pwd, pwd_len))
1180
        goto failed;
1181
#endif
1182

1183
    if(mbedtls_pk_get_type(pkey) != MBEDTLS_PK_ECKEY)
1184
        goto failed;
1185

1186
    *ctx = LIBSSH2_ALLOC(session, sizeof(libssh2_ecdsa_ctx));
1187

1188
    if(!*ctx)
1189
        goto failed;
1190

1191
    mbedtls_ecdsa_init(*ctx);
1192

1193
    if(mbedtls_ecdsa_from_keypair(*ctx, mbedtls_pk_ec(*pkey)) == 0)
1194
        return 0;
1195

1196
failed:
1197

1198
    _libssh2_mbedtls_ecdsa_free(*ctx);
1199
    *ctx = NULL;
1200

1201
    return -1;
1202
}
1203

1204
static int
1205
_libssh2_mbedtls_parse_openssh_key(libssh2_ecdsa_ctx **ctx,
1206
                                   LIBSSH2_SESSION *session,
1207
                                   const unsigned char *data,
1208
                                   size_t data_len,
1209
                                   const unsigned char *pwd)
1210
{
1211
    libssh2_curve_type type;
1212
    unsigned char *name = NULL;
1213
    struct string_buf *decrypted = NULL;
1214
    size_t curvelen, exponentlen, pointlen;
1215
    unsigned char *curve, *exponent, *point_buf;
1216

1217
    if(_libssh2_openssh_pem_parse_memory(session, pwd,
1218
                                         (const char *)data, data_len,
1219
                                         &decrypted))
1220
        goto failed;
1221

1222
    if(_libssh2_get_string(decrypted, &name, NULL))
1223
        goto failed;
1224

1225
    if(_libssh2_mbedtls_ecdsa_curve_type_from_name((const char *)name,
1226
                                                   &type))
1227
        goto failed;
1228

1229
    if(_libssh2_get_string(decrypted, &curve, &curvelen))
1230
        goto failed;
1231

1232
    if(_libssh2_get_string(decrypted, &point_buf, &pointlen))
1233
        goto failed;
1234

1235
    if(_libssh2_get_bignum_bytes(decrypted, &exponent, &exponentlen))
1236
        goto failed;
1237

1238
    *ctx = LIBSSH2_ALLOC(session, sizeof(libssh2_ecdsa_ctx));
1239

1240
    if(!*ctx)
1241
        goto failed;
1242

1243
    mbedtls_ecdsa_init(*ctx);
1244

1245
    if(mbedtls_ecp_group_load(&(*ctx)->MBEDTLS_PRIVATE(grp),
1246
                              (mbedtls_ecp_group_id)type))
1247
        goto failed;
1248

1249
    if(mbedtls_mpi_read_binary(&(*ctx)->MBEDTLS_PRIVATE(d),
1250
                               exponent, exponentlen))
1251
        goto failed;
1252

1253
    if(mbedtls_ecp_mul(&(*ctx)->MBEDTLS_PRIVATE(grp),
1254
                       &(*ctx)->MBEDTLS_PRIVATE(Q),
1255
                       &(*ctx)->MBEDTLS_PRIVATE(d),
1256
                       &(*ctx)->MBEDTLS_PRIVATE(grp).G,
1257
                       mbedtls_ctr_drbg_random,
1258
                       &_libssh2_mbedtls_ctr_drbg))
1259
        goto failed;
1260

1261
    if(mbedtls_ecp_check_privkey(&(*ctx)->MBEDTLS_PRIVATE(grp),
1262
                                 &(*ctx)->MBEDTLS_PRIVATE(d)) == 0)
1263
        goto cleanup;
1264

1265
failed:
1266

1267
    _libssh2_mbedtls_ecdsa_free(*ctx);
1268
    *ctx = NULL;
1269

1270
cleanup:
1271

1272
    if(decrypted) {
1273
        _libssh2_string_buf_free(session, decrypted);
1274
    }
1275

1276
    return *ctx ? 0 : -1;
1277
}
1278

1279
/* _libssh2_ecdsa_new_private
1280
 *
1281
 * Creates a new private key given a file path and password
1282
 *
1283
 */
1284

1285
int
1286
_libssh2_mbedtls_ecdsa_new_private(libssh2_ecdsa_ctx **ctx,
1287
                                   LIBSSH2_SESSION *session,
1288
                                   const char *filename,
1289
                                   const unsigned char *pwd)
1290
{
1291
    mbedtls_pk_context pkey;
1292
    unsigned char *data;
1293
    size_t data_len;
1294

1295
#if MBEDTLS_VERSION_NUMBER >= 0x03060000 && \
1296
    defined(_LIBSSH2_DISABLE_MBEDTLS36_PK_LOAD_FILE)
1297

1298
    /* FIXME: implement this functionality via a public API */
1299
    (void)session;
1300
    (void)filename;
1301
    (void)pwd;
1302
    data = NULL;
1303
    data_len = 0;
1304
#else
1305
    if(mbedtls_pk_load_file(filename, &data, &data_len))
1306
        goto cleanup;
1307

1308
    mbedtls_pk_init(&pkey);
1309

1310
    if(_libssh2_mbedtls_parse_eckey(ctx, &pkey, session,
1311
                                    data, data_len, pwd) == 0)
1312
        goto cleanup;
1313

1314
    _libssh2_mbedtls_parse_openssh_key(ctx, session, data, data_len, pwd);
1315

1316
cleanup:
1317
#endif
1318

1319
    mbedtls_pk_free(&pkey);
1320

1321
    _libssh2_mbedtls_safe_free(data, data_len);
1322

1323
    return *ctx ? 0 : -1;
1324
}
1325

1326
/* _libssh2_ecdsa_new_private
1327
 *
1328
 * Creates a new private key given a file data and password
1329
 *
1330
 */
1331

1332
int
1333
_libssh2_mbedtls_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx **ctx,
1334
                                              LIBSSH2_SESSION *session,
1335
                                              const char *data,
1336
                                              size_t data_len,
1337
                                              const unsigned char *pwd)
1338
{
1339
    unsigned char *ntdata;
1340
    mbedtls_pk_context pkey;
1341

1342
    mbedtls_pk_init(&pkey);
1343

1344
    ntdata = LIBSSH2_ALLOC(session, data_len + 1);
1345

1346
    if(!ntdata)
1347
        goto cleanup;
1348

1349
    memcpy(ntdata, data, data_len);
1350

1351
    if(_libssh2_mbedtls_parse_eckey(ctx, &pkey, session,
1352
                                    ntdata, data_len + 1, pwd) == 0)
1353
        goto cleanup;
1354

1355
    _libssh2_mbedtls_parse_openssh_key(ctx, session,
1356
                                       ntdata, data_len + 1, pwd);
1357

1358
cleanup:
1359

1360
    mbedtls_pk_free(&pkey);
1361

1362
    _libssh2_mbedtls_safe_free(ntdata, data_len);
1363

1364
    return *ctx ? 0 : -1;
1365
}
1366

1367
static unsigned char *
1368
_libssh2_mbedtls_mpi_write_binary(unsigned char *buf,
1369
                                  const mbedtls_mpi *mpi,
1370
                                  size_t bytes)
1371
{
1372
    unsigned char *p = buf;
1373
    uint32_t size = (uint32_t)bytes;
1374

1375
    if(sizeof(&p) / sizeof(p[0]) < 4) {
1376
        goto done;
1377
    }
1378

1379
    p += 4;
1380
    *p = 0;
1381

1382
    if(size > 0) {
1383
        mbedtls_mpi_write_binary(mpi, p + 1, size - 1);
1384
    }
1385

1386
    if(size > 0 && !(*(p + 1) & 0x80)) {
1387
        memmove(p, p + 1, --size);
1388
    }
1389

1390
    _libssh2_htonu32(p - 4, size);
1391

1392
done:
1393

1394
    return p + size;
1395
}
1396

1397
/* _libssh2_ecdsa_sign
1398
 *
1399
 * Computes the ECDSA signature of a previously-hashed message
1400
 *
1401
 */
1402

1403
int
1404
_libssh2_mbedtls_ecdsa_sign(LIBSSH2_SESSION *session,
1405
                            libssh2_ecdsa_ctx *ctx,
1406
                            const unsigned char *hash,
1407
                            size_t hash_len,
1408
                            unsigned char **sign,
1409
                            size_t *sign_len)
1410
{
1411
    size_t r_len, s_len, tmp_sign_len = 0;
1412
    unsigned char *sp, *tmp_sign = NULL;
1413
    mbedtls_mpi pr, ps;
1414

1415
    mbedtls_mpi_init(&pr);
1416
    mbedtls_mpi_init(&ps);
1417

1418
    if(mbedtls_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), &pr, &ps,
1419
                          &ctx->MBEDTLS_PRIVATE(d),
1420
                          hash, hash_len,
1421
                          mbedtls_ctr_drbg_random,
1422
                          &_libssh2_mbedtls_ctr_drbg))
1423
        goto cleanup;
1424

1425
    r_len = mbedtls_mpi_size(&pr) + 1;
1426
    s_len = mbedtls_mpi_size(&ps) + 1;
1427
    tmp_sign_len = r_len + s_len + 8;
1428

1429
    tmp_sign = LIBSSH2_CALLOC(session, tmp_sign_len);
1430

1431
    if(!tmp_sign)
1432
        goto cleanup;
1433

1434
    sp = tmp_sign;
1435
    sp = _libssh2_mbedtls_mpi_write_binary(sp, &pr, r_len);
1436
    sp = _libssh2_mbedtls_mpi_write_binary(sp, &ps, s_len);
1437

1438
    *sign_len = (size_t)(sp - tmp_sign);
1439

1440
    *sign = LIBSSH2_CALLOC(session, *sign_len);
1441

1442
    if(!*sign)
1443
        goto cleanup;
1444

1445
    memcpy(*sign, tmp_sign, *sign_len);
1446

1447
cleanup:
1448

1449
    mbedtls_mpi_free(&pr);
1450
    mbedtls_mpi_free(&ps);
1451

1452
    _libssh2_mbedtls_safe_free(tmp_sign, tmp_sign_len);
1453

1454
    return *sign ? 0 : -1;
1455
}
1456

1457
/* _libssh2_ecdsa_get_curve_type
1458
 *
1459
 * returns key curve type that maps to libssh2_curve_type
1460
 *
1461
 */
1462

1463
libssh2_curve_type
1464
_libssh2_mbedtls_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ctx)
1465
{
1466
    return (libssh2_curve_type) ctx->MBEDTLS_PRIVATE(grp).id;
1467
}
1468

1469
/* _libssh2_ecdsa_curve_type_from_name
1470
 *
1471
 * returns 0 for success, key curve type that maps to libssh2_curve_type
1472
 *
1473
 */
1474

1475
int
1476
_libssh2_mbedtls_ecdsa_curve_type_from_name(const char *name,
1477
                                            libssh2_curve_type *out_type)
1478
{
1479
    int ret = 0;
1480
    libssh2_curve_type type;
1481

1482
    if(!name || strlen(name) != 19)
1483
        return -1;
1484

1485
    if(strcmp(name, "ecdsa-sha2-nistp256") == 0)
1486
        type = LIBSSH2_EC_CURVE_NISTP256;
1487
    else if(strcmp(name, "ecdsa-sha2-nistp384") == 0)
1488
        type = LIBSSH2_EC_CURVE_NISTP384;
1489
    else if(strcmp(name, "ecdsa-sha2-nistp521") == 0)
1490
        type = LIBSSH2_EC_CURVE_NISTP521;
1491
    else {
1492
        ret = -1;
1493
    }
1494

1495
    if(ret == 0 && out_type) {
1496
        *out_type = type;
1497
    }
1498

1499
    return ret;
1500
}
1501

1502
void
1503
_libssh2_mbedtls_ecdsa_free(libssh2_ecdsa_ctx *ctx)
1504
{
1505
    mbedtls_ecdsa_free(ctx);
1506
    mbedtls_free(ctx);
1507
}
1508
#endif /* LIBSSH2_ECDSA */
1509

1510

1511
/* _libssh2_supported_key_sign_algorithms
1512
 *
1513
 * Return supported key hash algo upgrades, see crypto.h
1514
 *
1515
 */
1516

1517
const char *
1518
_libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
1519
                                       unsigned char *key_method,
1520
                                       size_t key_method_len)
1521
{
1522
    (void)session;
1523

1524
#if LIBSSH2_RSA_SHA2
1525
    if(key_method_len == 7 &&
1526
       memcmp(key_method, "ssh-rsa", key_method_len) == 0) {
1527
        return "rsa-sha2-512,rsa-sha2-256"
1528
#if LIBSSH2_RSA_SHA1
1529
            ",ssh-rsa"
1530
#endif
1531
            ;
1532
    }
1533
#endif
1534

1535
    return NULL;
1536
}
1537

1538
#endif /* LIBSSH2_CRYPTO_C */
1539

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.