summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2021-10-23 14:48:33 +0000
committertb <>2021-10-23 14:48:33 +0000
commitbbbf84f2ed93d2384ef90bd8529a667c3f8cbc46 (patch)
treef1eee73077eef60165f5647e96778b173f5daa5c /src
parent48d78838532f827ee48f8f73f24be6e77d4bbf0f (diff)
downloadopenbsd-bbbf84f2ed93d2384ef90bd8529a667c3f8cbc46.tar.gz
openbsd-bbbf84f2ed93d2384ef90bd8529a667c3f8cbc46.tar.bz2
openbsd-bbbf84f2ed93d2384ef90bd8529a667c3f8cbc46.zip
Prepare pcks12 for opaque structs in libcrypto
get_cert_chain() needs some error checking. return X509_V_ errors instead of trying to overload the NULL and then whine in a comment that this won't really work. Fix a bug that printed only the first attribute by factoring out the thing that did the actual printing. Sprinkle a few changes to accessors here and there. This is loosely based on what OpenSSL did with some simplifications by jsing. ok beck jsing
Diffstat (limited to 'src')
-rw-r--r--src/usr.bin/openssl/pkcs12.c139
1 files changed, 70 insertions, 69 deletions
diff --git a/src/usr.bin/openssl/pkcs12.c b/src/usr.bin/openssl/pkcs12.c
index d2e677ad84..4d5c0bbf21 100644
--- a/src/usr.bin/openssl/pkcs12.c
+++ b/src/usr.bin/openssl/pkcs12.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: pkcs12.c,v 1.14 2019/07/26 12:35:59 inoguchi Exp $ */ 1/* $OpenBSD: pkcs12.c,v 1.15 2021/10/23 14:48:33 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project. 3 * project.
4 */ 4 */
@@ -84,10 +84,10 @@ int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, char *pass,
84 int passlen, int options, char *pempass); 84 int passlen, int options, char *pempass);
85int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, 85int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass,
86 int passlen, int options, char *pempass); 86 int passlen, int options, char *pempass);
87int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, 87int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst,
88 const char *name); 88 const char *name);
89void hex_prin(BIO *out, unsigned char *buf, int len); 89void hex_prin(BIO *out, unsigned char *buf, int len);
90int alg_print(BIO *x, X509_ALGOR *alg); 90int alg_print(BIO *x, const X509_ALGOR *alg);
91int cert_load(BIO *in, STACK_OF(X509) *sk); 91int cert_load(BIO *in, STACK_OF(X509) *sk);
92static int set_pbe(BIO *err, int *ppbe, const char *str); 92static int set_pbe(BIO *err, int *ppbe, const char *str);
93 93
@@ -692,7 +692,7 @@ pkcs12_main(int argc, char **argv)
692 vret = get_cert_chain(ucert, store, &chain2); 692 vret = get_cert_chain(ucert, store, &chain2);
693 X509_STORE_free(store); 693 X509_STORE_free(store);
694 694
695 if (!vret) { 695 if (vret == X509_V_OK) {
696 /* Exclude verified certificate */ 696 /* Exclude verified certificate */
697 for (i = 1; i < sk_X509_num(chain2); i++) 697 for (i = 1; i < sk_X509_num(chain2); i++)
698 sk_X509_push(certs, sk_X509_value( 698 sk_X509_push(certs, sk_X509_value(
@@ -701,7 +701,7 @@ pkcs12_main(int argc, char **argv)
701 X509_free(sk_X509_value(chain2, 0)); 701 X509_free(sk_X509_value(chain2, 0));
702 sk_X509_free(chain2); 702 sk_X509_free(chain2);
703 } else { 703 } else {
704 if (vret >= 0) 704 if (vret != X509_V_ERR_UNSPECIFIED)
705 BIO_printf(bio_err, 705 BIO_printf(bio_err,
706 "Error %s getting chain.\n", 706 "Error %s getting chain.\n",
707 X509_verify_cert_error_string( 707 X509_verify_cert_error_string(
@@ -895,9 +895,9 @@ dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass,
895 return 1; 895 return 1;
896 print_attribs(out, bag->attrib, "Bag Attributes"); 896 print_attribs(out, bag->attrib, "Bag Attributes");
897 p8 = bag->value.keybag; 897 p8 = bag->value.keybag;
898 if (!(pkey = EVP_PKCS82PKEY(p8))) 898 if ((pkey = EVP_PKCS82PKEY(p8)) == NULL)
899 return 0; 899 return 0;
900 print_attribs(out, p8->attributes, "Key Attributes"); 900 print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes");
901 PEM_write_bio_PrivateKey(out, pkey, pkcs12_config.enc, NULL, 0, 901 PEM_write_bio_PrivateKey(out, pkey, pkcs12_config.enc, NULL, 0,
902 NULL, pempass); 902 NULL, pempass);
903 EVP_PKEY_free(pkey); 903 EVP_PKEY_free(pkey);
@@ -917,7 +917,7 @@ dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass,
917 PKCS8_PRIV_KEY_INFO_free(p8); 917 PKCS8_PRIV_KEY_INFO_free(p8);
918 return 0; 918 return 0;
919 } 919 }
920 print_attribs(out, p8->attributes, "Key Attributes"); 920 print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes");
921 PKCS8_PRIV_KEY_INFO_free(p8); 921 PKCS8_PRIV_KEY_INFO_free(p8);
922 PEM_write_bio_PrivateKey(out, pkey, pkcs12_config.enc, NULL, 0, 922 PEM_write_bio_PrivateKey(out, pkey, pkcs12_config.enc, NULL, 0,
923 NULL, pempass); 923 NULL, pempass);
@@ -962,43 +962,33 @@ dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass,
962} 962}
963 963
964/* Given a single certificate return a verified chain or NULL if error */ 964/* Given a single certificate return a verified chain or NULL if error */
965
966/* Hope this is OK .... */
967
968int 965int
969get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **chain) 966get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **out_chain)
970{ 967{
971 X509_STORE_CTX store_ctx; 968 X509_STORE_CTX *store_ctx = NULL;
972 STACK_OF(X509) *chn; 969 STACK_OF(X509) *chain = NULL;
973 int i = 0; 970 int ret = X509_V_ERR_UNSPECIFIED;
974 971
975 /* 972 if ((store_ctx = X509_STORE_CTX_new()) == NULL)
976 * FIXME: Should really check the return status of
977 * X509_STORE_CTX_init for an error, but how that fits into the
978 * return value of this function is less obvious.
979 */
980 X509_STORE_CTX_init(&store_ctx, store, cert, NULL);
981 if (X509_verify_cert(&store_ctx) <= 0) {
982 i = X509_STORE_CTX_get_error(&store_ctx);
983 if (i == 0)
984 /*
985 * avoid returning 0 if X509_verify_cert() did not
986 * set an appropriate error value in the context
987 */
988 i = -1;
989 chn = NULL;
990 goto err; 973 goto err;
991 } else 974 if (!X509_STORE_CTX_init(store_ctx, store, cert, NULL))
992 chn = X509_STORE_CTX_get1_chain(&store_ctx); 975 goto err;
976
977 if (X509_verify_cert(store_ctx) > 0) {
978 if ((chain = X509_STORE_CTX_get1_chain(store_ctx)) == NULL)
979 goto err;
980 }
981 ret = X509_STORE_CTX_get_error(store_ctx);
982
993 err: 983 err:
994 X509_STORE_CTX_cleanup(&store_ctx); 984 X509_STORE_CTX_free(store_ctx);
995 *chain = chn; 985 *out_chain = chain;
996 986
997 return i; 987 return ret;
998} 988}
999 989
1000int 990int
1001alg_print(BIO *x, X509_ALGOR *alg) 991alg_print(BIO *x, const X509_ALGOR *alg)
1002{ 992{
1003 PBEPARAM *pbe; 993 PBEPARAM *pbe;
1004 const unsigned char *p; 994 const unsigned char *p;
@@ -1031,14 +1021,45 @@ cert_load(BIO *in, STACK_OF(X509) *sk)
1031} 1021}
1032 1022
1033/* Generalised attribute print: handle PKCS#8 and bag attributes */ 1023/* Generalised attribute print: handle PKCS#8 and bag attributes */
1024void
1025print_attribute(BIO *out, const ASN1_TYPE *av)
1026{
1027 char *value;
1028
1029 switch (av->type) {
1030 case V_ASN1_BMPSTRING:
1031 value = OPENSSL_uni2asc(
1032 av->value.bmpstring->data,
1033 av->value.bmpstring->length);
1034 BIO_printf(out, "%s\n", value);
1035 free(value);
1036 break;
1037
1038 case V_ASN1_OCTET_STRING:
1039 hex_prin(out, av->value.octet_string->data,
1040 av->value.octet_string->length);
1041 BIO_printf(out, "\n");
1042 break;
1043
1044 case V_ASN1_BIT_STRING:
1045 hex_prin(out, av->value.bit_string->data,
1046 av->value.bit_string->length);
1047 BIO_printf(out, "\n");
1048 break;
1049
1050 default:
1051 BIO_printf(out, "<Unsupported tag %d>\n",
1052 av->type);
1053 break;
1054 }
1055}
1034 1056
1035int 1057int
1036print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, const char *name) 1058print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst, const char *name)
1037{ 1059{
1038 X509_ATTRIBUTE *attr; 1060 X509_ATTRIBUTE *attr;
1039 ASN1_TYPE *av; 1061 ASN1_TYPE *av;
1040 char *value; 1062 int i, j, attr_nid;
1041 int i, attr_nid;
1042 if (!attrlst) { 1063 if (!attrlst) {
1043 BIO_printf(out, "%s: <No Attributes>\n", name); 1064 BIO_printf(out, "%s: <No Attributes>\n", name);
1044 return 1; 1065 return 1;
@@ -1049,42 +1070,22 @@ print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, const char *name)
1049 } 1070 }
1050 BIO_printf(out, "%s\n", name); 1071 BIO_printf(out, "%s\n", name);
1051 for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) { 1072 for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
1073 ASN1_OBJECT *obj;
1074
1052 attr = sk_X509_ATTRIBUTE_value(attrlst, i); 1075 attr = sk_X509_ATTRIBUTE_value(attrlst, i);
1053 attr_nid = OBJ_obj2nid(attr->object); 1076 obj = X509_ATTRIBUTE_get0_object(attr);
1077 attr_nid = OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attr));
1054 BIO_printf(out, " "); 1078 BIO_printf(out, " ");
1055 if (attr_nid == NID_undef) { 1079 if (attr_nid == NID_undef) {
1056 i2a_ASN1_OBJECT(out, attr->object); 1080 i2a_ASN1_OBJECT(out, obj);
1057 BIO_printf(out, ": "); 1081 BIO_printf(out, ": ");
1058 } else 1082 } else
1059 BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid)); 1083 BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
1060 1084
1061 if (sk_ASN1_TYPE_num(attr->value.set)) { 1085 if (X509_ATTRIBUTE_count(attr)) {
1062 av = sk_ASN1_TYPE_value(attr->value.set, 0); 1086 for (j = 0; j < X509_ATTRIBUTE_count(attr); j++) {
1063 switch (av->type) { 1087 av = X509_ATTRIBUTE_get0_type(attr, j);
1064 case V_ASN1_BMPSTRING: 1088 print_attribute(out, av);
1065 value = OPENSSL_uni2asc(
1066 av->value.bmpstring->data,
1067 av->value.bmpstring->length);
1068 BIO_printf(out, "%s\n", value);
1069 free(value);
1070 break;
1071
1072 case V_ASN1_OCTET_STRING:
1073 hex_prin(out, av->value.octet_string->data,
1074 av->value.octet_string->length);
1075 BIO_printf(out, "\n");
1076 break;
1077
1078 case V_ASN1_BIT_STRING:
1079 hex_prin(out, av->value.bit_string->data,
1080 av->value.bit_string->length);
1081 BIO_printf(out, "\n");
1082 break;
1083
1084 default:
1085 BIO_printf(out, "<Unsupported tag %d>\n",
1086 av->type);
1087 break;
1088 } 1089 }
1089 } else 1090 } else
1090 BIO_printf(out, "<No Values>\n"); 1091 BIO_printf(out, "<No Values>\n");