Пример #1
0
bool rsa_ssh1_decrypt_pkcs1(mp_int *input, RSAKey *key,
                            strbuf *outbuf)
{
    strbuf *data = strbuf_new_nm();
    bool success = false;
    BinarySource src[1];

    {
        mp_int *b = rsa_ssh1_decrypt(input, key);
        for (size_t i = (mp_get_nbits(key->modulus) + 7) / 8; i-- > 0 ;) {
            put_byte(data, mp_get_byte(b, i));
        }
        mp_free(b);
    }

    BinarySource_BARE_INIT(src, data->u, data->len);

    /* Check PKCS#1 formatting prefix */
    if (get_byte(src) != 0) goto out;
    if (get_byte(src) != 2) goto out;
    while (1) {
        unsigned char byte = get_byte(src);
        if (get_err(src)) goto out;
        if (byte == 0)
            break;
    }

    /* Everything else is the payload */
    success = true;
    put_data(outbuf, get_ptr(src), get_avail(src));

  out:
    strbuf_free(data);
    return success;
}
Пример #2
0
int ssh2_censor_packet(
    const PacketLogSettings *pls, int type, int sender_is_client,
    ptrlen pkt, logblank_t *blanks)
{
    int nblanks = 0;
    ptrlen str;
    BinarySource src[1];

    BinarySource_BARE_INIT(src, pkt.ptr, pkt.len);

    if (pls->omit_data &&
        (type == SSH2_MSG_CHANNEL_DATA ||
         type == SSH2_MSG_CHANNEL_EXTENDED_DATA)) {
        /* "Session data" packets - omit the data string. */
        get_uint32(src);              /* skip channel id */
        if (type == SSH2_MSG_CHANNEL_EXTENDED_DATA)
            get_uint32(src);          /* skip extended data type */
        str = get_string(src);
        if (!get_err(src)) {
            assert(nblanks < MAX_BLANKS);
            blanks[nblanks].offset = src->pos - str.len;
            blanks[nblanks].type = PKTLOG_OMIT;
            blanks[nblanks].len = str.len;
            nblanks++;
        }
    }

    if (sender_is_client && pls->omit_passwords) {
        if (type == SSH2_MSG_USERAUTH_REQUEST) {
            /* If this is a password packet, blank the password(s). */
            get_string(src);              /* username */
            get_string(src);              /* service name */
            str = get_string(src);        /* auth method */
            if (ptrlen_eq_string(str, "password")) {
                get_bool(src);
                /* Blank the password field. */
                str = get_string(src);
                if (!get_err(src)) {
                    assert(nblanks < MAX_BLANKS);
                    blanks[nblanks].offset = src->pos - str.len;
                    blanks[nblanks].type = PKTLOG_BLANK;
                    blanks[nblanks].len = str.len;
                    nblanks++;
                    /* If there's another password field beyond it
                     * (change of password), blank that too. */
                    str = get_string(src);
                    if (!get_err(src))
                        blanks[nblanks-1].len =
                            src->pos - blanks[nblanks].offset;
                }
            }
        } else if (pls->actx == SSH2_PKTCTX_KBDINTER &&
                   type == SSH2_MSG_USERAUTH_INFO_RESPONSE) {
            /* If this is a keyboard-interactive response packet,
             * blank the responses. */
            get_uint32(src);
            assert(nblanks < MAX_BLANKS);
            blanks[nblanks].offset = src->pos;
            blanks[nblanks].type = PKTLOG_BLANK;
            do {
                str = get_string(src);
            } while (!get_err(src));
            blanks[nblanks].len = src->pos - blanks[nblanks].offset;
            nblanks++;
        } else if (type == SSH2_MSG_CHANNEL_REQUEST) {
            /*
             * If this is an X forwarding request packet, blank the
             * fake auth data.
             *
             * Note that while we blank the X authentication data
             * here, we don't take any special action to blank the
             * start of an X11 channel, so using MIT-MAGIC-COOKIE-1
             * and actually opening an X connection without having
             * session blanking enabled is likely to leak your cookie
             * into the log.
             */
            get_uint32(src);
            str = get_string(src);
            if (ptrlen_eq_string(str, "x11-req")) {
                get_bool(src);
                get_bool(src);
                get_string(src);
                str = get_string(src);
                if (!get_err(src)) {
                    assert(nblanks < MAX_BLANKS);
                    blanks[nblanks].offset = src->pos - str.len;
                    blanks[nblanks].type = PKTLOG_BLANK;
                    blanks[nblanks].len = str.len;
                    nblanks++;
                }
            }
        }
    }

    return nblanks;
}
Пример #3
0
mp_int *ssh_rsakex_decrypt(
    RSAKey *rsa, const ssh_hashalg *h, ptrlen ciphertext)
{
    mp_int *b1, *b2;
    int outlen, i;
    unsigned char *out;
    unsigned char labelhash[64];
    ssh_hash *hash;
    BinarySource src[1];
    const int HLEN = h->hlen;

    /*
     * Decryption side of the RSA key exchange operation.
     */

    /* The length of the encrypted data should be exactly the length
     * in octets of the RSA modulus.. */
    outlen = (7 + mp_get_nbits(rsa->modulus)) / 8;
    if (ciphertext.len != outlen)
        return NULL;

    /* Do the RSA decryption, and extract the result into a byte array. */
    b1 = mp_from_bytes_be(ciphertext);
    b2 = rsa_privkey_op(b1, rsa);
    out = snewn(outlen, unsigned char);
    for (i = 0; i < outlen; i++)
        out[i] = mp_get_byte(b2, outlen-1-i);
    mp_free(b1);
    mp_free(b2);

    /* Do the OAEP masking operations, in the reverse order from encryption */
    oaep_mask(h, out+HLEN+1, outlen-HLEN-1, out+1, HLEN);
    oaep_mask(h, out+1, HLEN, out+HLEN+1, outlen-HLEN-1);

    /* Check the leading byte is zero. */
    if (out[0] != 0) {
        sfree(out);
        return NULL;
    }
    /* Check the label hash at position 1+HLEN */
    assert(HLEN <= lenof(labelhash));
    hash = ssh_hash_new(h);
    ssh_hash_final(hash, labelhash);
    if (memcmp(out + HLEN + 1, labelhash, HLEN)) {
        sfree(out);
        return NULL;
    }
    /* Expect zero bytes followed by a 1 byte */
    for (i = 1 + 2 * HLEN; i < outlen; i++) {
        if (out[i] == 1) {
            i++;  /* skip over the 1 byte */
            break;
        } else if (out[i] != 1) {
            sfree(out);
            return NULL;
        }
    }
    /* And what's left is the input message data, which should be
     * encoded as an ordinary SSH-2 mpint. */
    BinarySource_BARE_INIT(src, out + i, outlen - i);
    b1 = get_mp_ssh2(src);
    sfree(out);
    if (get_err(src) || get_avail(src) != 0) {
        mp_free(b1);
        return NULL;
    }

    /* Success! */
    return b1;
}