Skip to content

Commit

Permalink
New function PKC12_newpass()
Browse files Browse the repository at this point in the history
  • Loading branch information
snhenson committed Dec 3, 1999
1 parent 6ea5314 commit 21131f0
Show file tree
Hide file tree
Showing 7 changed files with 255 additions and 10 deletions.
4 changes: 4 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

Changes between 0.9.4 and 0.9.5 [xx XXX 1999]

*) New function PKCS12_newpass() which changes the password of a
PKCS12 structure.
[Steve Henson]

*) Modify X509_TRUST and X509_PURPOSE so it also uses a static and
dynamic mix. In both cases the ids can be used as an index into the
table. Also modified the X509_TRUST_add() and X509_PURPOSE_add()
Expand Down
21 changes: 19 additions & 2 deletions crypto/pkcs12/Makefile.ssl
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC= p12_add.c p12_attr.c p12_bags.c p12_crpt.c p12_crt.c p12_decr.c \
p12_init.c p12_key.c p12_kiss.c p12_lib.c p12_mac.c p12_mutl.c\
p12_sbag.c p12_utl.c pk12err.c
p12_sbag.c p12_utl.c p12_npas.c pk12err.c
LIBOBJ= p12_add.o p12_attr.o p12_bags.o p12_crpt.o p12_crt.o p12_decr.o \
p12_init.o p12_key.o p12_kiss.o p12_lib.o p12_mac.o p12_mutl.o\
p12_sbag.o p12_utl.o pk12err.o
p12_sbag.o p12_utl.o p12_npas.o pk12err.o

SRC= $(LIBSRC)

Expand Down Expand Up @@ -293,6 +293,23 @@ p12_mutl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
p12_mutl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
p12_mutl.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
p12_mutl.o: ../cryptlib.h
p12_npas.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
p12_npas.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
p12_npas.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h
p12_npas.o: ../../include/openssl/des.h ../../include/openssl/dh.h
p12_npas.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
p12_npas.o: ../../include/openssl/err.h ../../include/openssl/evp.h
p12_npas.o: ../../include/openssl/idea.h ../../include/openssl/md2.h
p12_npas.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
p12_npas.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
p12_npas.o: ../../include/openssl/opensslv.h ../../include/openssl/pem.h
p12_npas.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs12.h
p12_npas.o: ../../include/openssl/pkcs7.h ../../include/openssl/rc2.h
p12_npas.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
p12_npas.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
p12_npas.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
p12_npas.o: ../../include/openssl/stack.h ../../include/openssl/x509.h
p12_npas.o: ../../include/openssl/x509_vfy.h
p12_sbag.o: ../../include/openssl/asn1.h ../../include/openssl/asn1_mac.h
p12_sbag.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
p12_sbag.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
Expand Down
212 changes: 212 additions & 0 deletions crypto/pkcs12/p12_npas.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
/* p12_npas.c */
/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* 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. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* [email protected].
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED 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 OpenSSL PROJECT OR
* ITS 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.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* ([email protected]). This product includes software written by Tim
* Hudson ([email protected]).
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/pkcs12.h>

/* PKCS#12 password change routine */

static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass);
static int newpass_bags(STACK *bags, char *oldpass, char *newpass);
static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass);
static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen);

/*
* Change the password on a PKCS#12 structure.
*/

int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass)
{

/* Check for NULL PKCS12 structure */

if(!p12) {
PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_INVALID_NULL_PKCS12_POINTER);
return 0;
}

/* Check the mac */

if (!PKCS12_verify_mac(p12, oldpass, -1)) {
PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_MAC_VERIFY_FAILURE);
return 0;
}

if (!newpass_p12(p12, oldpass, newpass)) {
PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_PARSE_ERROR);
return 0;
}

return 1;

}

/* Parse the outer PKCS#12 structure */

static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
{
STACK *asafes, *newsafes, *bags;
int i, bagnid, pbe_nid, pbe_iter, pbe_saltlen;
PKCS7 *p7, *p7new;
ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL;
unsigned char mac[EVP_MAX_MD_SIZE];
unsigned int maclen;
if (!(asafes = M_PKCS12_unpack_authsafes(p12))) return 0;
if(!(newsafes = sk_new(NULL))) return 0;
for (i = 0; i < sk_num (asafes); i++) {
p7 = (PKCS7 *) sk_value(asafes, i);
bagnid = OBJ_obj2nid(p7->type);
if (bagnid == NID_pkcs7_data) {
bags = M_PKCS12_unpack_p7data(p7);
} else if (bagnid == NID_pkcs7_encrypted) {
bags = M_PKCS12_unpack_p7encdata(p7, oldpass, -1);
alg_get(p7->d.encrypted->enc_data->algorithm,
&pbe_nid, &pbe_iter, &pbe_saltlen);
} else continue;
if (!bags) {
sk_pop_free(asafes, PKCS7_free);
return 0;
}
if (!newpass_bags(bags, oldpass, newpass)) {
sk_pop_free(bags, PKCS12_SAFEBAG_free);
sk_pop_free(asafes, PKCS7_free);
return 0;
}
/* Repack bag in same form with new password */
if (bagnid == NID_pkcs7_data) p7new = PKCS12_pack_p7data(bags);
else p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL,
pbe_saltlen, pbe_iter, bags);
sk_pop_free(bags, PKCS12_SAFEBAG_free);
if(!p7new) {
sk_pop_free(asafes, PKCS7_free);
return 0;
}
sk_push(newsafes, (char *)p7new);
}
sk_pop_free(asafes, PKCS7_free);

/* Repack safe: save old safe in case of error */

p12_data_tmp = p12->authsafes->d.data;
if(!(p12->authsafes->d.data = ASN1_OCTET_STRING_new())) goto saferr;
if(!M_PKCS12_pack_authsafes(p12, newsafes)) goto saferr;

if(!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) goto saferr;
if(!(macnew = ASN1_OCTET_STRING_new())) goto saferr;
if(!ASN1_OCTET_STRING_set(macnew, mac, maclen)) goto saferr;
ASN1_OCTET_STRING_free(p12->mac->dinfo->digest);
p12->mac->dinfo->digest = macnew;
ASN1_OCTET_STRING_free(p12_data_tmp);

return 1;

saferr:
/* Restore old safe */
ASN1_OCTET_STRING_free(p12->authsafes->d.data);
ASN1_OCTET_STRING_free(macnew);
p12->authsafes->d.data = p12_data_tmp;
return 0;

}


static int newpass_bags(STACK *bags, char *oldpass, char *newpass)
{
int i;
for (i = 0; i < sk_num(bags); i++) {
if (!newpass_bag((PKCS12_SAFEBAG *)sk_value(bags, i),
oldpass, newpass)) return 0;
}
return 1;
}

/* Change password of safebag: only needs handle shrouded keybags */

static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass)
{
PKCS8_PRIV_KEY_INFO *p8;
X509_SIG *p8new;
int p8_nid, p8_saltlen, p8_iter;

if(M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) return 1;

if (!(p8 = M_PKCS12_decrypt_skey(bag, oldpass, -1))) return 0;
alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, &p8_saltlen);
if(!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
p8_iter, p8))) return 0;
X509_SIG_free(bag->value.shkeybag);
bag->value.shkeybag = p8new;
return 1;
}

static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen)
{
PBEPARAM *pbe;
unsigned char *p;
p = alg->parameter->value.sequence->data;
pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
*pnid = OBJ_obj2nid(alg->algorithm);
*piter = ASN1_INTEGER_get(pbe->iter);
*psaltlen = pbe->salt->length;
PBEPARAM_free(pbe);
return 0;
}
1 change: 1 addition & 0 deletions crypto/pkcs12/pk12err.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ static ERR_STRING_DATA PKCS12_str_functs[]=
{ERR_PACK(0,PKCS12_F_PKCS12_KEY_GEN_UNI,0), "PKCS12_key_gen_uni"},
{ERR_PACK(0,PKCS12_F_PKCS12_MAKE_KEYBAG,0), "PKCS12_MAKE_KEYBAG"},
{ERR_PACK(0,PKCS12_F_PKCS12_MAKE_SHKEYBAG,0), "PKCS12_MAKE_SHKEYBAG"},
{ERR_PACK(0,PKCS12_F_PKCS12_NEWPASS,0), "PKCS12_NEWPASS"},
{ERR_PACK(0,PKCS12_F_PKCS12_PACK_P7DATA,0), "PKCS12_pack_p7data"},
{ERR_PACK(0,PKCS12_F_PKCS12_PACK_P7ENCDATA,0), "PKCS12_pack_p7encdata"},
{ERR_PACK(0,PKCS12_F_PKCS12_PACK_SAFEBAG,0), "PKCS12_pack_safebag"},
Expand Down
2 changes: 2 additions & 0 deletions crypto/pkcs12/pkcs12.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12);
int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12);
PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12);
PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12);
int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass);

/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
Expand All @@ -296,6 +297,7 @@ PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12);
#define PKCS12_F_PKCS12_KEY_GEN_UNI 111
#define PKCS12_F_PKCS12_MAKE_KEYBAG 112
#define PKCS12_F_PKCS12_MAKE_SHKEYBAG 113
#define PKCS12_F_PKCS12_NEWPASS 128
#define PKCS12_F_PKCS12_PACK_P7DATA 114
#define PKCS12_F_PKCS12_PACK_P7ENCDATA 115
#define PKCS12_F_PKCS12_PACK_SAFEBAG 117
Expand Down
24 changes: 16 additions & 8 deletions doc/openssl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -494,16 +494,16 @@ extension in a human or machine readable form.

1. Initialisation and cleanup.

X509V3_add_standard_extensions();

This function should be called before any other extension code. It adds support
for some common PKIX and Netscape extensions. Additional custom extensions can
be added as well (see later).
No special initialisation is needed before calling the extension functions.
You used to have to call X509V3_add_standard_extensions(); but this is no longer
required and this function no longer does anything.

void X509V3_EXT_cleanup(void);

This function should be called last to cleanup the extension code. After this
call no other extension calls should be made.
This function should be called to cleanup the extension code if any custom
extensions have been added. If no custom extensions have been added then this
call does nothing. After this call all custom extension code is freed up but
you can still use the standard extensions.

2. Printing and parsing extensions.

Expand Down Expand Up @@ -917,7 +917,7 @@ d2i_PKCS12_fp(fp, p12)

This is the same but for a FILE pointer.

3. Parsing and creation functions.
3. High level functions.

3.1 Parsing with PKCS12_parse().

Expand Down Expand Up @@ -955,6 +955,14 @@ p12 = PKCS12_create(pass, "My Certificate", pkey, cert, NULL, 0,0,0,0,0);
i2d_PKCS12_fp(fp, p12);
PKCS12_free(p12);

3.3 Changing a PKCS#12 structure password.

int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass);

This changes the password of an already existing PKCS#12 structure. oldpass
is the old password and newpass is the new one. An error occurs if the old
password is incorrect.

LOW LEVEL FUNCTIONS.

In some cases the high level functions do not provide the necessary
Expand Down
1 change: 1 addition & 0 deletions util/libeay.num
Original file line number Diff line number Diff line change
Expand Up @@ -2113,3 +2113,4 @@ DIRECTORYSTRING_new 2137
sk_ASN1_STRING_TABLE_new 2138
sk_X509_TRUST_delete 2139
X509_add_trust_object 2140
PKCS12_newpass 2141

0 comments on commit 21131f0

Please sign in to comment.