diff options
author | djm <> | 2008-09-06 12:17:54 +0000 |
---|---|---|
committer | djm <> | 2008-09-06 12:17:54 +0000 |
commit | 38ce604e3cc97706b876b0525ddff0121115456d (patch) | |
tree | 7ccc28afe1789ea3dbedf72365f955d5b8e105b5 /src/lib/libcrypto/x509v3/v3_utl.c | |
parent | 12867252827c8efaa8ddd1fa3b3d6e321e2bcdef (diff) | |
download | openbsd-38ce604e3cc97706b876b0525ddff0121115456d.tar.gz openbsd-38ce604e3cc97706b876b0525ddff0121115456d.tar.bz2 openbsd-38ce604e3cc97706b876b0525ddff0121115456d.zip |
resolve conflicts
Diffstat (limited to 'src/lib/libcrypto/x509v3/v3_utl.c')
-rw-r--r-- | src/lib/libcrypto/x509v3/v3_utl.c | 343 |
1 files changed, 338 insertions, 5 deletions
diff --git a/src/lib/libcrypto/x509v3/v3_utl.c b/src/lib/libcrypto/x509v3/v3_utl.c index f23a8d29a0..57be441399 100644 --- a/src/lib/libcrypto/x509v3/v3_utl.c +++ b/src/lib/libcrypto/x509v3/v3_utl.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* v3_utl.c */ | 1 | /* v3_utl.c */ |
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL |
3 | * project 1999. | 3 | * project. |
4 | */ | 4 | */ |
5 | /* ==================================================================== | 5 | /* ==================================================================== |
6 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | 6 | * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions |
@@ -63,6 +63,7 @@ | |||
63 | #include "cryptlib.h" | 63 | #include "cryptlib.h" |
64 | #include <openssl/conf.h> | 64 | #include <openssl/conf.h> |
65 | #include <openssl/x509v3.h> | 65 | #include <openssl/x509v3.h> |
66 | #include <openssl/bn.h> | ||
66 | 67 | ||
67 | static char *strip_spaces(char *name); | 68 | static char *strip_spaces(char *name); |
68 | static int sk_strcmp(const char * const *a, const char * const *b); | 69 | static int sk_strcmp(const char * const *a, const char * const *b); |
@@ -70,6 +71,11 @@ static STACK *get_email(X509_NAME *name, GENERAL_NAMES *gens); | |||
70 | static void str_free(void *str); | 71 | static void str_free(void *str); |
71 | static int append_ia5(STACK **sk, ASN1_IA5STRING *email); | 72 | static int append_ia5(STACK **sk, ASN1_IA5STRING *email); |
72 | 73 | ||
74 | static int ipv4_from_asc(unsigned char *v4, const char *in); | ||
75 | static int ipv6_from_asc(unsigned char *v6, const char *in); | ||
76 | static int ipv6_cb(const char *elem, int len, void *usr); | ||
77 | static int ipv6_hex(unsigned char *out, const char *in, int inlen); | ||
78 | |||
73 | /* Add a CONF_VALUE name value pair to stack */ | 79 | /* Add a CONF_VALUE name value pair to stack */ |
74 | 80 | ||
75 | int X509V3_add_value(const char *name, const char *value, | 81 | int X509V3_add_value(const char *name, const char *value, |
@@ -156,11 +162,11 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value) | |||
156 | ASN1_INTEGER *aint; | 162 | ASN1_INTEGER *aint; |
157 | int isneg, ishex; | 163 | int isneg, ishex; |
158 | int ret; | 164 | int ret; |
159 | bn = BN_new(); | ||
160 | if (!value) { | 165 | if (!value) { |
161 | X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_INVALID_NULL_VALUE); | 166 | X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_INVALID_NULL_VALUE); |
162 | return 0; | 167 | return 0; |
163 | } | 168 | } |
169 | bn = BN_new(); | ||
164 | if (value[0] == '-') { | 170 | if (value[0] == '-') { |
165 | value++; | 171 | value++; |
166 | isneg = 1; | 172 | isneg = 1; |
@@ -174,7 +180,8 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value) | |||
174 | if (ishex) ret = BN_hex2bn(&bn, value); | 180 | if (ishex) ret = BN_hex2bn(&bn, value); |
175 | else ret = BN_dec2bn(&bn, value); | 181 | else ret = BN_dec2bn(&bn, value); |
176 | 182 | ||
177 | if (!ret) { | 183 | if (!ret || value[ret]) { |
184 | BN_free(bn); | ||
178 | X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_DEC2BN_ERROR); | 185 | X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_DEC2BN_ERROR); |
179 | return 0; | 186 | return 0; |
180 | } | 187 | } |
@@ -358,7 +365,7 @@ char *hex_to_string(unsigned char *buffer, long len) | |||
358 | char *tmp, *q; | 365 | char *tmp, *q; |
359 | unsigned char *p; | 366 | unsigned char *p; |
360 | int i; | 367 | int i; |
361 | static char hexdig[] = "0123456789ABCDEF"; | 368 | const static char hexdig[] = "0123456789ABCDEF"; |
362 | if(!buffer || !len) return NULL; | 369 | if(!buffer || !len) return NULL; |
363 | if(!(tmp = OPENSSL_malloc(len * 3 + 1))) { | 370 | if(!(tmp = OPENSSL_malloc(len * 3 + 1))) { |
364 | X509V3err(X509V3_F_HEX_TO_STRING,ERR_R_MALLOC_FAILURE); | 371 | X509V3err(X509V3_F_HEX_TO_STRING,ERR_R_MALLOC_FAILURE); |
@@ -466,6 +473,30 @@ STACK *X509_get1_email(X509 *x) | |||
466 | return ret; | 473 | return ret; |
467 | } | 474 | } |
468 | 475 | ||
476 | STACK *X509_get1_ocsp(X509 *x) | ||
477 | { | ||
478 | AUTHORITY_INFO_ACCESS *info; | ||
479 | STACK *ret = NULL; | ||
480 | int i; | ||
481 | info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL); | ||
482 | if (!info) | ||
483 | return NULL; | ||
484 | for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) | ||
485 | { | ||
486 | ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i); | ||
487 | if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) | ||
488 | { | ||
489 | if (ad->location->type == GEN_URI) | ||
490 | { | ||
491 | if (!append_ia5(&ret, ad->location->d.uniformResourceIdentifier)) | ||
492 | break; | ||
493 | } | ||
494 | } | ||
495 | } | ||
496 | AUTHORITY_INFO_ACCESS_free(info); | ||
497 | return ret; | ||
498 | } | ||
499 | |||
469 | STACK *X509_REQ_get1_email(X509_REQ *x) | 500 | STACK *X509_REQ_get1_email(X509_REQ *x) |
470 | { | 501 | { |
471 | GENERAL_NAMES *gens; | 502 | GENERAL_NAMES *gens; |
@@ -533,3 +564,305 @@ void X509_email_free(STACK *sk) | |||
533 | { | 564 | { |
534 | sk_pop_free(sk, str_free); | 565 | sk_pop_free(sk, str_free); |
535 | } | 566 | } |
567 | |||
568 | /* Convert IP addresses both IPv4 and IPv6 into an | ||
569 | * OCTET STRING compatible with RFC3280. | ||
570 | */ | ||
571 | |||
572 | ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc) | ||
573 | { | ||
574 | unsigned char ipout[16]; | ||
575 | ASN1_OCTET_STRING *ret; | ||
576 | int iplen; | ||
577 | |||
578 | /* If string contains a ':' assume IPv6 */ | ||
579 | |||
580 | iplen = a2i_ipadd(ipout, ipasc); | ||
581 | |||
582 | if (!iplen) | ||
583 | return NULL; | ||
584 | |||
585 | ret = ASN1_OCTET_STRING_new(); | ||
586 | if (!ret) | ||
587 | return NULL; | ||
588 | if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) | ||
589 | { | ||
590 | ASN1_OCTET_STRING_free(ret); | ||
591 | return NULL; | ||
592 | } | ||
593 | return ret; | ||
594 | } | ||
595 | |||
596 | ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc) | ||
597 | { | ||
598 | ASN1_OCTET_STRING *ret = NULL; | ||
599 | unsigned char ipout[32]; | ||
600 | char *iptmp = NULL, *p; | ||
601 | int iplen1, iplen2; | ||
602 | p = strchr(ipasc,'/'); | ||
603 | if (!p) | ||
604 | return NULL; | ||
605 | iptmp = BUF_strdup(ipasc); | ||
606 | if (!iptmp) | ||
607 | return NULL; | ||
608 | p = iptmp + (p - ipasc); | ||
609 | *p++ = 0; | ||
610 | |||
611 | iplen1 = a2i_ipadd(ipout, iptmp); | ||
612 | |||
613 | if (!iplen1) | ||
614 | goto err; | ||
615 | |||
616 | iplen2 = a2i_ipadd(ipout + iplen1, p); | ||
617 | |||
618 | OPENSSL_free(iptmp); | ||
619 | iptmp = NULL; | ||
620 | |||
621 | if (!iplen2 || (iplen1 != iplen2)) | ||
622 | goto err; | ||
623 | |||
624 | ret = ASN1_OCTET_STRING_new(); | ||
625 | if (!ret) | ||
626 | goto err; | ||
627 | if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2)) | ||
628 | goto err; | ||
629 | |||
630 | return ret; | ||
631 | |||
632 | err: | ||
633 | if (iptmp) | ||
634 | OPENSSL_free(iptmp); | ||
635 | if (ret) | ||
636 | ASN1_OCTET_STRING_free(ret); | ||
637 | return NULL; | ||
638 | } | ||
639 | |||
640 | |||
641 | int a2i_ipadd(unsigned char *ipout, const char *ipasc) | ||
642 | { | ||
643 | /* If string contains a ':' assume IPv6 */ | ||
644 | |||
645 | if (strchr(ipasc, ':')) | ||
646 | { | ||
647 | if (!ipv6_from_asc(ipout, ipasc)) | ||
648 | return 0; | ||
649 | return 16; | ||
650 | } | ||
651 | else | ||
652 | { | ||
653 | if (!ipv4_from_asc(ipout, ipasc)) | ||
654 | return 0; | ||
655 | return 4; | ||
656 | } | ||
657 | } | ||
658 | |||
659 | static int ipv4_from_asc(unsigned char *v4, const char *in) | ||
660 | { | ||
661 | int a0, a1, a2, a3; | ||
662 | if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) | ||
663 | return 0; | ||
664 | if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) | ||
665 | || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255)) | ||
666 | return 0; | ||
667 | v4[0] = a0; | ||
668 | v4[1] = a1; | ||
669 | v4[2] = a2; | ||
670 | v4[3] = a3; | ||
671 | return 1; | ||
672 | } | ||
673 | |||
674 | typedef struct { | ||
675 | /* Temporary store for IPV6 output */ | ||
676 | unsigned char tmp[16]; | ||
677 | /* Total number of bytes in tmp */ | ||
678 | int total; | ||
679 | /* The position of a zero (corresponding to '::') */ | ||
680 | int zero_pos; | ||
681 | /* Number of zeroes */ | ||
682 | int zero_cnt; | ||
683 | } IPV6_STAT; | ||
684 | |||
685 | |||
686 | static int ipv6_from_asc(unsigned char *v6, const char *in) | ||
687 | { | ||
688 | IPV6_STAT v6stat; | ||
689 | v6stat.total = 0; | ||
690 | v6stat.zero_pos = -1; | ||
691 | v6stat.zero_cnt = 0; | ||
692 | /* Treat the IPv6 representation as a list of values | ||
693 | * separated by ':'. The presence of a '::' will parse | ||
694 | * as one, two or three zero length elements. | ||
695 | */ | ||
696 | if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat)) | ||
697 | return 0; | ||
698 | |||
699 | /* Now for some sanity checks */ | ||
700 | |||
701 | if (v6stat.zero_pos == -1) | ||
702 | { | ||
703 | /* If no '::' must have exactly 16 bytes */ | ||
704 | if (v6stat.total != 16) | ||
705 | return 0; | ||
706 | } | ||
707 | else | ||
708 | { | ||
709 | /* If '::' must have less than 16 bytes */ | ||
710 | if (v6stat.total == 16) | ||
711 | return 0; | ||
712 | /* More than three zeroes is an error */ | ||
713 | if (v6stat.zero_cnt > 3) | ||
714 | return 0; | ||
715 | /* Can only have three zeroes if nothing else present */ | ||
716 | else if (v6stat.zero_cnt == 3) | ||
717 | { | ||
718 | if (v6stat.total > 0) | ||
719 | return 0; | ||
720 | } | ||
721 | /* Can only have two zeroes if at start or end */ | ||
722 | else if (v6stat.zero_cnt == 2) | ||
723 | { | ||
724 | if ((v6stat.zero_pos != 0) | ||
725 | && (v6stat.zero_pos != v6stat.total)) | ||
726 | return 0; | ||
727 | } | ||
728 | else | ||
729 | /* Can only have one zero if *not* start or end */ | ||
730 | { | ||
731 | if ((v6stat.zero_pos == 0) | ||
732 | || (v6stat.zero_pos == v6stat.total)) | ||
733 | return 0; | ||
734 | } | ||
735 | } | ||
736 | |||
737 | /* Format result */ | ||
738 | |||
739 | /* Copy initial part */ | ||
740 | if (v6stat.zero_pos > 0) | ||
741 | memcpy(v6, v6stat.tmp, v6stat.zero_pos); | ||
742 | /* Zero middle */ | ||
743 | if (v6stat.total != 16) | ||
744 | memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); | ||
745 | /* Copy final part */ | ||
746 | if (v6stat.total != v6stat.zero_pos) | ||
747 | memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, | ||
748 | v6stat.tmp + v6stat.zero_pos, | ||
749 | v6stat.total - v6stat.zero_pos); | ||
750 | |||
751 | return 1; | ||
752 | } | ||
753 | |||
754 | static int ipv6_cb(const char *elem, int len, void *usr) | ||
755 | { | ||
756 | IPV6_STAT *s = usr; | ||
757 | /* Error if 16 bytes written */ | ||
758 | if (s->total == 16) | ||
759 | return 0; | ||
760 | if (len == 0) | ||
761 | { | ||
762 | /* Zero length element, corresponds to '::' */ | ||
763 | if (s->zero_pos == -1) | ||
764 | s->zero_pos = s->total; | ||
765 | /* If we've already got a :: its an error */ | ||
766 | else if (s->zero_pos != s->total) | ||
767 | return 0; | ||
768 | s->zero_cnt++; | ||
769 | } | ||
770 | else | ||
771 | { | ||
772 | /* If more than 4 characters could be final a.b.c.d form */ | ||
773 | if (len > 4) | ||
774 | { | ||
775 | /* Need at least 4 bytes left */ | ||
776 | if (s->total > 12) | ||
777 | return 0; | ||
778 | /* Must be end of string */ | ||
779 | if (elem[len]) | ||
780 | return 0; | ||
781 | if (!ipv4_from_asc(s->tmp + s->total, elem)) | ||
782 | return 0; | ||
783 | s->total += 4; | ||
784 | } | ||
785 | else | ||
786 | { | ||
787 | if (!ipv6_hex(s->tmp + s->total, elem, len)) | ||
788 | return 0; | ||
789 | s->total += 2; | ||
790 | } | ||
791 | } | ||
792 | return 1; | ||
793 | } | ||
794 | |||
795 | /* Convert a string of up to 4 hex digits into the corresponding | ||
796 | * IPv6 form. | ||
797 | */ | ||
798 | |||
799 | static int ipv6_hex(unsigned char *out, const char *in, int inlen) | ||
800 | { | ||
801 | unsigned char c; | ||
802 | unsigned int num = 0; | ||
803 | if (inlen > 4) | ||
804 | return 0; | ||
805 | while(inlen--) | ||
806 | { | ||
807 | c = *in++; | ||
808 | num <<= 4; | ||
809 | if ((c >= '0') && (c <= '9')) | ||
810 | num |= c - '0'; | ||
811 | else if ((c >= 'A') && (c <= 'F')) | ||
812 | num |= c - 'A' + 10; | ||
813 | else if ((c >= 'a') && (c <= 'f')) | ||
814 | num |= c - 'a' + 10; | ||
815 | else | ||
816 | return 0; | ||
817 | } | ||
818 | out[0] = num >> 8; | ||
819 | out[1] = num & 0xff; | ||
820 | return 1; | ||
821 | } | ||
822 | |||
823 | |||
824 | int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk, | ||
825 | unsigned long chtype) | ||
826 | { | ||
827 | CONF_VALUE *v; | ||
828 | int i, mval; | ||
829 | char *p, *type; | ||
830 | if (!nm) | ||
831 | return 0; | ||
832 | |||
833 | for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) | ||
834 | { | ||
835 | v=sk_CONF_VALUE_value(dn_sk,i); | ||
836 | type=v->name; | ||
837 | /* Skip past any leading X. X: X, etc to allow for | ||
838 | * multiple instances | ||
839 | */ | ||
840 | for(p = type; *p ; p++) | ||
841 | #ifndef CHARSET_EBCDIC | ||
842 | if ((*p == ':') || (*p == ',') || (*p == '.')) | ||
843 | #else | ||
844 | if ((*p == os_toascii[':']) || (*p == os_toascii[',']) || (*p == os_toascii['.'])) | ||
845 | #endif | ||
846 | { | ||
847 | p++; | ||
848 | if(*p) type = p; | ||
849 | break; | ||
850 | } | ||
851 | #ifndef CHARSET_EBCDIC | ||
852 | if (*type == '+') | ||
853 | #else | ||
854 | if (*type == os_toascii['+']) | ||
855 | #endif | ||
856 | { | ||
857 | mval = -1; | ||
858 | type++; | ||
859 | } | ||
860 | else | ||
861 | mval = 0; | ||
862 | if (!X509_NAME_add_entry_by_txt(nm,type, chtype, | ||
863 | (unsigned char *) v->value,-1,-1,mval)) | ||
864 | return 0; | ||
865 | |||
866 | } | ||
867 | return 1; | ||
868 | } | ||