/*
  zip_source_pkware_encode.c -- Traditional PKWARE encryption routines
  Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner

  This file is part of libzip, a library to manipulate ZIP archives.
  The authors can be contacted at <libzip@nih.at>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.
  3. The names of the authors may not be used to endorse or promote
     products derived from this software without specific prior
     written permission.

  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/


#include <stdlib.h>
#include <string.h>

#include "zipint.h"

struct trad_pkware {
    char *password;
    zip_pkware_keys_t keys;
    zip_buffer_t *buffer;
    bool eof;
    zip_error_t error;
};


static int encrypt_header(zip_source_t *, struct trad_pkware *);
static zip_int64_t pkware_encrypt(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
static void trad_pkware_free(struct trad_pkware *);
static struct trad_pkware *trad_pkware_new(const char *password, zip_error_t *error);


zip_source_t *
zip_source_pkware_encode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) {
    struct trad_pkware *ctx;
    zip_source_t *s2;

    if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
        zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return NULL;
    }
    if (!(flags & ZIP_CODEC_ENCODE)) {
        zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
        return NULL;
    }

    if ((ctx = trad_pkware_new(password, &za->error)) == NULL) {
        return NULL;
    }

    if ((s2 = zip_source_layered(za, src, pkware_encrypt, ctx)) == NULL) {
        trad_pkware_free(ctx);
        return NULL;
    }

    return s2;
}


static int
encrypt_header(zip_source_t *src, struct trad_pkware *ctx) {
    struct zip_stat st;
    unsigned short dostime, dosdate;
    zip_uint8_t *header;

    if (zip_source_stat(src, &st) != 0) {
        _zip_error_set_from_source(&ctx->error, src);
        return -1;
    }

    _zip_u2d_time(st.mtime, &dostime, &dosdate);

    if ((ctx->buffer = _zip_buffer_new(NULL, ZIP_CRYPTO_PKWARE_HEADERLEN)) == NULL) {
        zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
        return -1;
    }

    header = _zip_buffer_data(ctx->buffer);

    /* generate header from random bytes and mtime
       see appnote.iz, XIII. Decryption, Step 2, last paragraph */
    if (!zip_secure_random(header, ZIP_CRYPTO_PKWARE_HEADERLEN - 1)) {
        zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
        _zip_buffer_free(ctx->buffer);
        ctx->buffer = NULL;
        return -1;
    }
    header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] = (zip_uint8_t)((dostime >> 8) & 0xff);

    _zip_pkware_encrypt(&ctx->keys, header, header, ZIP_CRYPTO_PKWARE_HEADERLEN);

    return 0;
}


static zip_int64_t
pkware_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length, zip_source_cmd_t cmd) {
    struct trad_pkware *ctx;
    zip_int64_t n;
    zip_uint64_t buffer_n;

    ctx = (struct trad_pkware *)ud;

    switch (cmd) {
    case ZIP_SOURCE_OPEN:
        ctx->eof = false;

        /* initialize keys */
        _zip_pkware_keys_reset(&ctx->keys);
        _zip_pkware_encrypt(&ctx->keys, NULL, (const zip_uint8_t *)ctx->password, strlen(ctx->password));

        if (encrypt_header(src, ctx) < 0) {
            return -1;
        }
        return 0;

    case ZIP_SOURCE_READ:
        buffer_n = 0;

        if (ctx->buffer) {
            /* write header values to data */
            buffer_n = _zip_buffer_read(ctx->buffer, data, length);
            data = (zip_uint8_t *)data + buffer_n;
            length -= buffer_n;

            if (_zip_buffer_eof(ctx->buffer)) {
                _zip_buffer_free(ctx->buffer);
                ctx->buffer = NULL;
            }
        }

        if (ctx->eof) {
            return (zip_int64_t)buffer_n;
        }

        if ((n = zip_source_read(src, data, length)) < 0) {
            _zip_error_set_from_source(&ctx->error, src);
            return -1;
        }

        _zip_pkware_encrypt(&ctx->keys, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n);

        if ((zip_uint64_t)n < length) {
            ctx->eof = true;
        }

        return (zip_int64_t)buffer_n + n;

    case ZIP_SOURCE_CLOSE:
        _zip_buffer_free(ctx->buffer);
        ctx->buffer = NULL;
        return 0;

    case ZIP_SOURCE_STAT: {
        zip_stat_t *st;

        st = (zip_stat_t *)data;
        st->encryption_method = ZIP_EM_TRAD_PKWARE;
        st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
        if (st->valid & ZIP_STAT_COMP_SIZE) {
            st->comp_size += ZIP_CRYPTO_PKWARE_HEADERLEN;
        }

        return 0;
    }

    case ZIP_SOURCE_GET_FILE_ATTRIBUTES: {
        zip_file_attributes_t *attributes = (zip_file_attributes_t *)data;
        if (length < sizeof(*attributes)) {
            zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
            return -1;
        }
        attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED;
        attributes->version_needed = 20;

        return 0;
    }

    case ZIP_SOURCE_SUPPORTS:
        return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1);

    case ZIP_SOURCE_ERROR:
        return zip_error_to_data(&ctx->error, data, length);

    case ZIP_SOURCE_FREE:
        trad_pkware_free(ctx);
        return 0;

    default:
        zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
        return -1;
    }
}


static struct trad_pkware *
trad_pkware_new(const char *password, zip_error_t *error) {
    struct trad_pkware *ctx;

    if ((ctx = (struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
        zip_error_set(error, ZIP_ER_MEMORY, 0);
        return NULL;
    }

    if ((ctx->password = strdup(password)) == NULL) {
        zip_error_set(error, ZIP_ER_MEMORY, 0);
        free(ctx);
        return NULL;
    }
    ctx->buffer = NULL;
    zip_error_init(&ctx->error);

    return ctx;
}


static void
trad_pkware_free(struct trad_pkware *ctx) {
    if (ctx == NULL) {
        return;
    }

    free(ctx->password);
    _zip_buffer_free(ctx->buffer);
    zip_error_fini(&ctx->error);
    free(ctx);
}
