/*
  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);
}
