/* symencrypt.c - show how to enrypt a string symmetrically
 *      Copyright (c) 1999 by Michael Roth <mroth@gnupg.org>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * MICHALE ROTH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name of Michael Roth shall not be
 * used in advertising or otherwise to promote the sale, use or other dealings
 * in this Software without prior written authorization from Michael Roth.
 */


#include <stdio.h>
#include <pgg.h>


char * message = "Hello World!\n";
char * passphrase = "secret";
char * comment = "The passphrase of this message is `secret' !";


int main()
{
    PggSymcrypt		sc = NULL;
    PggStdio		stdio = NULL;
    PggOutopts		opts = NULL;
    PggInput		input = NULL;
    PggOutput		output = NULL;
    PggBuffer		result = NULL;
    PggErrenv		errenv;
    
    
    /*
     * The error environment tracks and catches all errors. This call
     * reset the error environment and clear any errors set in the
     * environment.
     */
    pgg_errenv_reset(errenv);
    
    
    /*
     * A PggStdio carries the input source and output destination,
     * and some further options to produce the output.
     */
    stdio = pgg_stdio_new(errenv);
    
    
    /*
     * We create a new PggInput object to determine the source of the
     * data we wish to encrypt. Then we set the raw C string 
     * with our message as source. After that, we add the PggInput object
     * to the PggStdio object, which will be used by PggSymcrypt later.
     */
    input = pgg_input_new(errenv);
    pgg_input_set_rawdata(input, message, strlen(message), errenv);
    pgg_stdio_set_input(stdio, input, errenv);
    
    
    /*
     * The same as for input is needed for the resulting encrypted 
     * output. However, because we don't know how large the encrypted
     * message will be, we create a PggBuffer thats purpose is to
     * manage dynamically growing memory. Additionally we need
     * a PggOutput object set with the PggBuffer as destination
     * to write to. The PggOutput object is added to the PggStdio.
     */
    result = pgg_buffer_new(errenv);
    output = pgg_output_new(errenv);
    pgg_output_set_buffer(output, result, errenv);
    pgg_stdio_set_output(stdio, output, errenv);
    
    
    /*
     * Because we would like to produce ASCII armored output and 
     * would like to submit our own comment in the encrypted message,
     * we create a PggOutopts object and request the desired options
     * and finally add this PggOutopts object to the PggStdio
     * object.
     */
    opts = pgg_outopts_new(errenv);
    pgg_outopts_set_armor(opts, 1, errenv);		/* ascii armored output */
    pgg_outopts_set_comment(opts, comment, errenv);	/* user defined comment string */
    pgg_outopts_set_version(opts, 0, errenv);		/* don't create a version string */
    pgg_stdio_set_outopts(stdio, opts, errenv);
    
    
    /*
     * A PggSymcrypt is the actual workhorse used for encrypting 
     * a message conventionally. We set the passphrase used for encryption
     * and the PggStdio object to specify the source and destination 
     * of all data.
     */
    sc = pgg_symcrypt_new(errenv);
    pgg_symcrypt_set_passphrase(sc, passphrase, errenv);
    pgg_symcrypt_set_stdio(sc, stdio, errenv);
    
    
    /*
     * This call actually does the complete work of calling GnuPG and 
     * parsing GnuPG messages and outputs. When this call is finished,
     * the encrypted message is stored in the PggBuffer named `result'.
     */
    pgg_symcrypt_encrypt(sc, errenv);
    
    
    /*
     * Because we would like to have a C string as result of the 
     * enrypted data, we need to append a simple 0 character at
     * the end of the encrypted data.
     */
    pgg_buffer_append(result, "", 1, errenv);
    
    
    /*
     * Now we check if their was an error in the calls above.
     */
    if (pgg_errenv_is_set(errenv)) {
        printf("An error occured\n");
        return 1;
    }
    
    
    /*
     * Now we simple print the resulting message. We don't submit the
     * error environment because it is very unlikly that this call will
     * fail if all previous calls succeded. However, in generall it's
     * always a good idea to catch all possible errors.
     */
    printf("%s", (char *)pgg_buffer_get_data(result, NULL));
    
    
    /*
     * When the various Pgg Objects are no longer needed, don't forgett to
     * release them to prevent memory leaks. Because we are not interested
     * in errors caused by releasing objects we set the error environment
     * to NULL.
     */
    pgg_buffer_release(result, NULL);
    pgg_output_release(output, NULL);
    pgg_outopts_release(opts, NULL);
    pgg_input_release(input, NULL);
    pgg_stdio_release(stdio, NULL);
    pgg_symcrypt_release(sc, NULL);
    
    return 0;
}





