/* crypto/asn1/n_pkey.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * 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 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. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR OR CONTRIBUTORS 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.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#include <openssl/opensslconf.h>
#if !defined(OPENSSL_SYS_STARBOARD)
#include <stdio.h>
#endif  // !defined(OPENSSL_SYS_STARBOARD)
#include "cryptlib.h"
#ifndef OPENSSL_NO_RSA
# include <openssl/rsa.h>
# include <openssl/objects.h>
# include <openssl/asn1t.h>
# include <openssl/asn1_mac.h>
# include <openssl/evp.h>
# include <openssl/x509.h>

# ifndef OPENSSL_NO_RC4

typedef struct netscape_pkey_st {
    long version;
    X509_ALGOR *algor;
    ASN1_OCTET_STRING *private_key;
} NETSCAPE_PKEY;

typedef struct netscape_encrypted_pkey_st {
    ASN1_OCTET_STRING *os;
    /*
     * This is the same structure as DigestInfo so use it: although this
     * isn't really anything to do with digests.
     */
    X509_SIG *enckey;
} NETSCAPE_ENCRYPTED_PKEY;


ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = {
        ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, os, ASN1_OCTET_STRING),
        ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG)
} ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY)

DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_PKEY)
IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)

ASN1_SEQUENCE(NETSCAPE_PKEY) = {
        ASN1_SIMPLE(NETSCAPE_PKEY, version, LONG),
        ASN1_SIMPLE(NETSCAPE_PKEY, algor, X509_ALGOR),
        ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(NETSCAPE_PKEY)

DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY)
IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)

static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
                          int (*cb) (char *buf, int len, const char *prompt,
                                     int verify), int sgckey);

int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
                     int (*cb) (char *buf, int len, const char *prompt,
                                int verify))
{
    return i2d_RSA_NET(a, pp, cb, 0);
}

int i2d_RSA_NET(const RSA *a, unsigned char **pp,
                int (*cb) (char *buf, int len, const char *prompt,
                           int verify), int sgckey)
{
    int i, j, ret = 0;
    int rsalen, pkeylen, olen;
    NETSCAPE_PKEY *pkey = NULL;
    NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
    unsigned char buf[256], *zz;
    unsigned char key[EVP_MAX_KEY_LENGTH];
    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);

    if (a == NULL)
        return (0);

    if ((pkey = NETSCAPE_PKEY_new()) == NULL)
        goto err;
    if ((enckey = NETSCAPE_ENCRYPTED_PKEY_new()) == NULL)
        goto err;
    pkey->version = 0;

    pkey->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
    if ((pkey->algor->parameter = ASN1_TYPE_new()) == NULL)
        goto err;
    pkey->algor->parameter->type = V_ASN1_NULL;

    rsalen = i2d_RSAPrivateKey(a, NULL);

    /*
     * Fake some octet strings just for the initial length calculation.
     */

    pkey->private_key->length = rsalen;

    pkeylen = i2d_NETSCAPE_PKEY(pkey, NULL);

    enckey->enckey->digest->length = pkeylen;

    enckey->os->length = 11;    /* "private-key" */

    enckey->enckey->algor->algorithm = OBJ_nid2obj(NID_rc4);
    if ((enckey->enckey->algor->parameter = ASN1_TYPE_new()) == NULL)
        goto err;
    enckey->enckey->algor->parameter->type = V_ASN1_NULL;

    if (pp == NULL) {
        olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL);
        NETSCAPE_PKEY_free(pkey);
        NETSCAPE_ENCRYPTED_PKEY_free(enckey);
        return olen;
    }

    /* Since its RC4 encrypted length is actual length */
    if ((zz = (unsigned char *)OPENSSL_malloc(rsalen)) == NULL) {
        ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    pkey->private_key->data = zz;
    /* Write out private key encoding */
    i2d_RSAPrivateKey(a, &zz);

    if ((zz = OPENSSL_malloc(pkeylen)) == NULL) {
        ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (!ASN1_STRING_set(enckey->os, "private-key", -1)) {
        ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    enckey->enckey->digest->data = zz;
    i2d_NETSCAPE_PKEY(pkey, &zz);

    /* Wipe the private key encoding */
    OPENSSL_cleanse(pkey->private_key->data, rsalen);

    if (cb == NULL)
        cb = EVP_read_pw_string;
    i = cb((char *)buf, 256, "Enter Private Key password:", 1);
    if (i != 0) {
        ASN1err(ASN1_F_I2D_RSA_NET, ASN1_R_BAD_PASSWORD_READ);
        goto err;
    }
    i = OPENSSL_port_strlen((char *)buf);
    /* If the key is used for SGC the algorithm is modified a little. */
    if (sgckey) {
        if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
            goto err;
        OPENSSL_port_memcpy(buf + 16, "SGCKEYSALT", 10);
        i = 26;
    }

    if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL))
        goto err;
    OPENSSL_cleanse(buf, 256);

    /* Encrypt private key in place */
    zz = enckey->enckey->digest->data;
    if (!EVP_EncryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL))
        goto err;
    if (!EVP_EncryptUpdate(&ctx, zz, &i, zz, pkeylen))
        goto err;
    if (!EVP_EncryptFinal_ex(&ctx, zz + i, &j))
        goto err;

    ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp);
 err:
    EVP_CIPHER_CTX_cleanup(&ctx);
    NETSCAPE_ENCRYPTED_PKEY_free(enckey);
    NETSCAPE_PKEY_free(pkey);
    return (ret);
}

RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
                      int (*cb) (char *buf, int len, const char *prompt,
                                 int verify))
{
    return d2i_RSA_NET(a, pp, length, cb, 0);
}

RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
                 int (*cb) (char *buf, int len, const char *prompt,
                            int verify), int sgckey)
{
    RSA *ret = NULL;
    const unsigned char *p;
    NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;

    p = *pp;

    enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length);
    if (!enckey) {
        ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_DECODING_ERROR);
        return NULL;
    }

    if ((enckey->os->length != 11) || (OPENSSL_port_strncmp("private-key",
                                               (char *)enckey->os->data,
                                               11) != 0)) {
        ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_PRIVATE_KEY_HEADER_MISSING);
        NETSCAPE_ENCRYPTED_PKEY_free(enckey);
        return NULL;
    }
    if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4) {
        ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM);
        goto err;
    }
    if (cb == NULL)
        cb = EVP_read_pw_string;
    if ((ret = d2i_RSA_NET_2(a, enckey->enckey->digest, cb, sgckey)) == NULL)
        goto err;

    *pp = p;

 err:
    NETSCAPE_ENCRYPTED_PKEY_free(enckey);
    return ret;

}

static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
                          int (*cb) (char *buf, int len, const char *prompt,
                                     int verify), int sgckey)
{
    NETSCAPE_PKEY *pkey = NULL;
    RSA *ret = NULL;
    int i, j;
    unsigned char buf[256];
    const unsigned char *zz;
    unsigned char key[EVP_MAX_KEY_LENGTH];
    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);

    i = cb((char *)buf, 256, "Enter Private Key password:", 0);
    if (i != 0) {
        ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_BAD_PASSWORD_READ);
        goto err;
    }

    i = OPENSSL_port_strlen((char *)buf);
    if (sgckey) {
        if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
            goto err;
        OPENSSL_port_memcpy(buf + 16, "SGCKEYSALT", 10);
        i = 26;
    }

    if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL))
        goto err;
    OPENSSL_cleanse(buf, 256);

    if (!EVP_DecryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL))
        goto err;
    if (!EVP_DecryptUpdate(&ctx, os->data, &i, os->data, os->length))
        goto err;
    if (!EVP_DecryptFinal_ex(&ctx, &(os->data[i]), &j))
        goto err;
    os->length = i + j;

    zz = os->data;

    if ((pkey = d2i_NETSCAPE_PKEY(NULL, &zz, os->length)) == NULL) {
        ASN1err(ASN1_F_D2I_RSA_NET_2,
                ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY);
        goto err;
    }

    zz = pkey->private_key->data;
    if ((ret = d2i_RSAPrivateKey(a, &zz, pkey->private_key->length)) == NULL) {
        ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_UNABLE_TO_DECODE_RSA_KEY);
        goto err;
    }
 err:
    EVP_CIPHER_CTX_cleanup(&ctx);
    NETSCAPE_PKEY_free(pkey);
    return (ret);
}

# endif                         /* OPENSSL_NO_RC4 */

#else                           /* !OPENSSL_NO_RSA */

# if PEDANTIC
static void *dummy = &dummy;
# endif

#endif
