~ubuntu-branches/debian/stretch/dropbear/stretch

« back to all changes in this revision

Viewing changes to common-kex.c

  • Committer: Package Import Robot
  • Author(s): Guilhem Moulin, Matt Johnston, Guilhem Moulin
  • Date: 2015-10-03 20:47:33 UTC
  • mfrom: (1.4.9)
  • Revision ID: package-import@ubuntu.com-20151003204733-4ututwekmkdnczsu
Tags: 2015.68-1
* New co-maintainer.

[ Matt Johnston ]
* New upstream release.  (Closes: #631858, #775222.)

[ Guilhem Moulin ]
* debian/source/format: 3.0 (quilt)
* debian/compat: 9
* debian/control:
  + Bump Standards-Version to 3.9.6 (no changes necessary).
  + Add Homepage, Vcs-Git, and Vcs-Browser fields.
* debian/copyright: add machine-readable file.
* Split up package in dropbear-bin (binaries), dropbear-run (init scripts)
  and dropbear-initramfs (initramfs integration).  'dropbear' is now a
  transitional dummy package depending on on dropbear-run and
  dropbear-initramfs.  (Closes: #692932.)
* Refactor the package using dh_* tools, including dh_autoreconf.  (Closes:
  #689618, #777324, #793006, #793917.)
* Add 'Multi-Arch: foreign' tags.
* dropbear-run:
  + Add a status option to the /etc/init.d script.
  + Pass key files with -r not -d in /etc/init.d script.  (Closes: #761143.)
  + Post-installation script: Generate missing ECDSA in addition to RSA and
    DSS host keys.  (Closes: #776976.)
* dropbear-initramfs:
  + No longer mark /usr/share/initramfs-tools/conf-hooks.d/dropbear as a
    configuration file, since it violates the Debian Policy Manual section
    10.7.2.  (Regression from 2014.64-1.)  Instead, move the file to
    /etc/initramfs-tools/conf-hooks.d/dropbear and add a symlink in
    /usr/share/initramfs-tools/conf-hooks.d.
  + Delete debian/initramfs/premount-devpts, since /dev/pts in mounted by
    init since initramfs-tools 0.94.  (Closes: #632656, #797939.)
  + Auto-generate host keys in the postinstall script, not when runing
    update-initramfs.  Pass the '-R' option (via $PKGOPTION_dropbear_OPTION)
    for the old behavior.  Also, print fingerprint and ASCII art for
    generated keys (if ssh-keygen is available).
  + Revert ad2fb1c and remove warning about changing host key.  Users
    shouldn't be encouraged to use the same keys in the encrypted partition
    and in the initramfs.  The proper fix is to use an alternative port or
    UserKnownHostFile.
  + Set ~root to `mktemp -d "$DESTDIR/root-XXXXXX"` to avoid collisions with
    $rootmnt.  (Closes: #558115.)
  + Exit gracefully if $IP is 'none' or 'off'.  (Closes: #692932.)
  + Start dropbear with flag -s to explicitly disable password logins.
  + Terminate all children before killing dropbear, to avoid stalled SSH
    connections.  (Closes: #735203.)
  + Run configure_networking in the foreground.  (Closes: #584780, #626181,
    #739519.)
  + Bring down interfaces and flush IP routes and addresses before exiting
    the ramdisk, to avoid dirty network configuration in the regular kernel.
    (Closes: #715048, #720987, #720988.)  The interfaces considered are
    those matching the $DROPBEAR_IFDOWN shell pattern (default: '*'); the
    special value 'none' keeps all interfaces up and preserves routing
    tables and addresses.

Show diffs side-by-side

added added

removed removed

Lines of Context:
238
238
void kexfirstinitialise() {
239
239
        ses.kexstate.donefirstkex = 0;
240
240
 
241
 
#ifndef DISABLE_ZLIB
242
 
        if (opts.enable_compress) {
243
 
                ses.compress_algos = ssh_compress;
244
 
        } else
245
 
#endif
 
241
#ifdef DISABLE_ZLIB
 
242
        ses.compress_algos = ssh_nocompress;
 
243
#else
 
244
        switch (opts.compress_mode)
246
245
        {
247
 
                ses.compress_algos = ssh_nocompress;
 
246
                case DROPBEAR_COMPRESS_DELAYED:
 
247
                        ses.compress_algos = ssh_delaycompress;
 
248
                        break;
 
249
 
 
250
                case DROPBEAR_COMPRESS_ON:
 
251
                        ses.compress_algos = ssh_compress;
 
252
                        break;
 
253
 
 
254
                case DROPBEAR_COMPRESS_OFF:
 
255
                        ses.compress_algos = ssh_nocompress;
 
256
                        break;
248
257
        }
 
258
#endif
249
259
        kexinitialise();
250
260
}
251
261
 
303
313
                hash_desc->done(&hs2, tmpout);
304
314
                memcpy(&out[offset], tmpout, MIN(outlen - offset, hash_desc->hashsize));
305
315
        }
306
 
 
 
316
        m_burn(&hs2, sizeof(hash_state));
307
317
}
308
318
 
309
319
/* Generate the actual encryption/integrity keys, using the results of the
403
413
        m_burn(C2S_key, sizeof(C2S_key));
404
414
        m_burn(S2C_IV, sizeof(S2C_IV));
405
415
        m_burn(S2C_key, sizeof(S2C_key));
 
416
        m_burn(&hs, sizeof(hash_state));
406
417
 
407
418
        TRACE(("leave gen_new_keys"))
408
419
}
500
511
 
501
512
        /* start the kex hash */
502
513
        local_ident_len = strlen(LOCAL_IDENT);
503
 
        remote_ident_len = strlen((char*)ses.remoteident);
 
514
        remote_ident_len = strlen(ses.remoteident);
504
515
 
505
516
        kexhashbuf_len = local_ident_len + remote_ident_len
506
517
                + ses.transkexinit->len + ses.payload->len
514
525
                read_kex_algos();
515
526
 
516
527
                /* V_C, the client's version string (CR and NL excluded) */
517
 
            buf_putstring(ses.kexhashbuf,
518
 
                        (unsigned char*)LOCAL_IDENT, local_ident_len);
 
528
            buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len);
519
529
                /* V_S, the server's version string (CR and NL excluded) */
520
530
            buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
521
531
 
522
532
                /* I_C, the payload of the client's SSH_MSG_KEXINIT */
523
533
            buf_putstring(ses.kexhashbuf,
524
 
                        ses.transkexinit->data, ses.transkexinit->len);
 
534
                        (const char*)ses.transkexinit->data, ses.transkexinit->len);
525
535
                /* I_S, the payload of the server's SSH_MSG_KEXINIT */
526
 
            buf_setpos(ses.payload, 0);
527
 
            buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len);
 
536
            buf_setpos(ses.payload, ses.payload_beginning);
 
537
            buf_putstring(ses.kexhashbuf, 
 
538
                (const char*)buf_getptr(ses.payload, ses.payload->len-ses.payload->pos),
 
539
                ses.payload->len-ses.payload->pos);
528
540
                ses.requirenext = SSH_MSG_KEXDH_REPLY;
529
541
        } else {
530
542
                /* SERVER */
534
546
                /* V_C, the client's version string (CR and NL excluded) */
535
547
            buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
536
548
                /* V_S, the server's version string (CR and NL excluded) */
 
549
            buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len);
 
550
 
 
551
                /* I_C, the payload of the client's SSH_MSG_KEXINIT */
 
552
            buf_setpos(ses.payload, ses.payload_beginning);
537
553
            buf_putstring(ses.kexhashbuf, 
538
 
                                (unsigned char*)LOCAL_IDENT, local_ident_len);
539
 
 
540
 
                /* I_C, the payload of the client's SSH_MSG_KEXINIT */
541
 
            buf_setpos(ses.payload, 0);
542
 
            buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len);
 
554
                (const char*)buf_getptr(ses.payload, ses.payload->len-ses.payload->pos),
 
555
                ses.payload->len-ses.payload->pos);
543
556
 
544
557
                /* I_S, the payload of the server's SSH_MSG_KEXINIT */
545
558
            buf_putstring(ses.kexhashbuf,
546
 
                        ses.transkexinit->data, ses.transkexinit->len);
 
559
                        (const char*)ses.transkexinit->data, ses.transkexinit->len);
547
560
 
548
561
                ses.requirenext = SSH_MSG_KEXDH_INIT;
549
562
        }
618
631
void kexdh_comb_key(struct kex_dh_param *param, mp_int *dh_pub_them,
619
632
                sign_key *hostkey) {
620
633
 
621
 
        mp_int dh_p;
 
634
        DEF_MP_INT(dh_p);
 
635
        DEF_MP_INT(dh_p_min1);
622
636
        mp_int *dh_e = NULL, *dh_f = NULL;
623
637
 
624
 
        /* read the prime and generator*/
625
 
        m_mp_init(&dh_p);
 
638
        m_mp_init_multi(&dh_p, &dh_p_min1, NULL);
626
639
        load_dh_p(&dh_p);
627
640
 
628
 
        /* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */
629
 
        if (mp_cmp(dh_pub_them, &dh_p) != MP_LT 
630
 
                        || mp_cmp_d(dh_pub_them, 0) != MP_GT) {
 
641
        if (mp_sub_d(&dh_p, 1, &dh_p_min1) != MP_OKAY) { 
 
642
                dropbear_exit("Diffie-Hellman error");
 
643
        }
 
644
 
 
645
        /* Check that dh_pub_them (dh_e or dh_f) is in the range [2, p-2] */
 
646
        if (mp_cmp(dh_pub_them, &dh_p_min1) != MP_LT 
 
647
                        || mp_cmp_d(dh_pub_them, 1) != MP_GT) {
631
648
                dropbear_exit("Diffie-Hellman error");
632
649
        }
633
650
        
638
655
        }
639
656
 
640
657
        /* clear no longer needed vars */
641
 
        mp_clear_multi(&dh_p, NULL);
 
658
        mp_clear_multi(&dh_p, &dh_p_min1, NULL);
642
659
 
643
660
        /* From here on, the code needs to work with the _same_ vars on each side,
644
661
         * not vice-versaing for client/server */
686
703
        ecc_key *Q_C, *Q_S, *Q_them;
687
704
 
688
705
        Q_them = buf_get_ecc_raw_pubkey(pub_them, algo_kex->ecc_curve);
 
706
        if (Q_them == NULL) {
 
707
                dropbear_exit("ECC error");
 
708
        }
689
709
 
690
710
        ses.dh_K = dropbear_ecc_shared_secret(Q_them, &param->key);
691
711
 
764
784
        /* K_S, the host key */
765
785
        buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey);
766
786
        /* Q_C, client's ephemeral public key octet string */
767
 
        buf_putstring(ses.kexhashbuf, Q_C, CURVE25519_LEN);
 
787
        buf_putstring(ses.kexhashbuf, (const char*)Q_C, CURVE25519_LEN);
768
788
        /* Q_S, server's ephemeral public key octet string */
769
 
        buf_putstring(ses.kexhashbuf, Q_S, CURVE25519_LEN);
 
789
        buf_putstring(ses.kexhashbuf, (const char*)Q_S, CURVE25519_LEN);
770
790
        /* K, the shared secret */
771
791
        buf_putmpint(ses.kexhashbuf, ses.dh_K);
772
792
 
798
818
 
799
819
        buf_burn(ses.kexhashbuf);
800
820
        buf_free(ses.kexhashbuf);
 
821
        m_burn(&hs, sizeof(hash_state));
801
822
        ses.kexhashbuf = NULL;
802
823
        
803
824
        /* first time around, we set the session_id to H */
805
826
                /* create the session_id, this never needs freeing */
806
827
                ses.session_id = buf_newcopy(ses.hash);
807
828
        }
808
 
 
809
829
}
810
830
 
811
831
/* read the other side's algo list. buf_match_algo is a callback to match