OLD | NEW |
1 /* ssl/kssl.c -*- mode: C; c-file-style: "eay" -*- */ | 1 /* ssl/kssl.c -*- mode: C; c-file-style: "eay" -*- */ |
2 /* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project 2000. | 2 /* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project 2000. |
3 */ | 3 */ |
4 /* ==================================================================== | 4 /* ==================================================================== |
5 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. | 5 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. |
6 * | 6 * |
7 * Redistribution and use in source and binary forms, with or without | 7 * Redistribution and use in source and binary forms, with or without |
8 * modification, are permitted provided that the following conditions | 8 * modification, are permitted provided that the following conditions |
9 * are met: | 9 * are met: |
10 * | 10 * |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 #include <openssl/opensslconf.h> | 69 #include <openssl/opensslconf.h> |
70 | 70 |
71 #include <string.h> | 71 #include <string.h> |
72 | 72 |
73 #define KRB5_PRIVATE 1 | 73 #define KRB5_PRIVATE 1 |
74 | 74 |
75 #include <openssl/ssl.h> | 75 #include <openssl/ssl.h> |
76 #include <openssl/evp.h> | 76 #include <openssl/evp.h> |
77 #include <openssl/objects.h> | 77 #include <openssl/objects.h> |
78 #include <openssl/krb5_asn.h> | 78 #include <openssl/krb5_asn.h> |
| 79 #include "kssl_lcl.h" |
79 | 80 |
80 #ifndef OPENSSL_NO_KRB5 | 81 #ifndef OPENSSL_NO_KRB5 |
81 | 82 |
82 #ifndef ENOMEM | 83 #ifndef ENOMEM |
83 #define ENOMEM KRB5KRB_ERR_GENERIC | 84 #define ENOMEM KRB5KRB_ERR_GENERIC |
84 #endif | 85 #endif |
85 | 86 |
86 /* | 87 /* |
87 * When OpenSSL is built on Windows, we do not want to require that | 88 * When OpenSSL is built on Windows, we do not want to require that |
88 * the Kerberos DLLs be available in order for the OpenSSL DLLs to | 89 * the Kerberos DLLs be available in order for the OpenSSL DLLs to |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 #define krb5_kt_close kssl_krb5_kt_close | 125 #define krb5_kt_close kssl_krb5_kt_close |
125 #endif /* krb5_kt_close */ | 126 #endif /* krb5_kt_close */ |
126 #ifndef krb5_kt_get_entry | 127 #ifndef krb5_kt_get_entry |
127 #define krb5_kt_get_entry kssl_krb5_kt_get_entry | 128 #define krb5_kt_get_entry kssl_krb5_kt_get_entry |
128 #endif /* krb5_kt_get_entry */ | 129 #endif /* krb5_kt_get_entry */ |
129 #define krb5_auth_con_init kssl_krb5_auth_con_init | 130 #define krb5_auth_con_init kssl_krb5_auth_con_init |
130 | 131 |
131 #define krb5_principal_compare kssl_krb5_principal_compare | 132 #define krb5_principal_compare kssl_krb5_principal_compare |
132 #define krb5_decrypt_tkt_part kssl_krb5_decrypt_tkt_part | 133 #define krb5_decrypt_tkt_part kssl_krb5_decrypt_tkt_part |
133 #define krb5_timeofday kssl_krb5_timeofday | 134 #define krb5_timeofday kssl_krb5_timeofday |
134 #define krb5_rc_default kssl_krb5_rc_default | 135 #define krb5_rc_default kssl_krb5_rc_default |
135 | 136 |
136 #ifdef krb5_rc_initialize | 137 #ifdef krb5_rc_initialize |
137 #undef krb5_rc_initialize | 138 #undef krb5_rc_initialize |
138 #endif | 139 #endif |
139 #define krb5_rc_initialize kssl_krb5_rc_initialize | 140 #define krb5_rc_initialize kssl_krb5_rc_initialize |
140 | 141 |
141 #ifdef krb5_rc_get_lifespan | 142 #ifdef krb5_rc_get_lifespan |
142 #undef krb5_rc_get_lifespan | 143 #undef krb5_rc_get_lifespan |
143 #endif | 144 #endif |
144 #define krb5_rc_get_lifespan kssl_krb5_rc_get_lifespan | 145 #define krb5_rc_get_lifespan kssl_krb5_rc_get_lifespan |
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
832 break; | 833 break; |
833 } | 834 } |
834 } | 835 } |
835 | 836 |
836 | 837 |
837 /* Return true:1 if p "looks like" the start of the real authenticator | 838 /* Return true:1 if p "looks like" the start of the real authenticator |
838 ** described in kssl_skip_confound() below. The ASN.1 pattern is | 839 ** described in kssl_skip_confound() below. The ASN.1 pattern is |
839 ** "62 xx 30 yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and | 840 ** "62 xx 30 yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and |
840 ** xx and yy are possibly multi-byte length fields. | 841 ** xx and yy are possibly multi-byte length fields. |
841 */ | 842 */ |
842 int » kssl_test_confound(unsigned char *p) | 843 static int » kssl_test_confound(unsigned char *p) |
843 { | 844 { |
844 int len = 2; | 845 int len = 2; |
845 int xx = 0, yy = 0; | 846 int xx = 0, yy = 0; |
846 | 847 |
847 if (*p++ != 0x62) return 0; | 848 if (*p++ != 0x62) return 0; |
848 if (*p > 0x82) return 0; | 849 if (*p > 0x82) return 0; |
849 switch(*p) { | 850 switch(*p) { |
850 case 0x82: p++; xx = (*p++ << 8); xx += *p++; break; | 851 case 0x82: p++; xx = (*p++ << 8); xx += *p++; break; |
851 case 0x81: p++; xx = *p++; break; | 852 case 0x81: p++; xx = *p++; break; |
852 case 0x80: return 0; | 853 case 0x80: return 0; |
(...skipping 14 matching lines...) Expand all Loading... |
867 /* Allocate, fill, and return cksumlens array of checksum lengths. | 868 /* Allocate, fill, and return cksumlens array of checksum lengths. |
868 ** This array holds just the unique elements from the krb5_cksumarray[]. | 869 ** This array holds just the unique elements from the krb5_cksumarray[]. |
869 ** array[n] == 0 signals end of data. | 870 ** array[n] == 0 signals end of data. |
870 ** | 871 ** |
871 ** The krb5_cksumarray[] was an internal variable that has since been | 872 ** The krb5_cksumarray[] was an internal variable that has since been |
872 ** replaced by a more general method for storing the data. It should | 873 ** replaced by a more general method for storing the data. It should |
873 ** not be used. Instead we use real API calls and make a guess for | 874 ** not be used. Instead we use real API calls and make a guess for |
874 ** what the highest assigned CKSUMTYPE_ constant is. As of 1.2.2 | 875 ** what the highest assigned CKSUMTYPE_ constant is. As of 1.2.2 |
875 ** it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3). So we will use 0x0010. | 876 ** it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3). So we will use 0x0010. |
876 */ | 877 */ |
877 size_t *populate_cksumlens(void) | 878 static size_t *populate_cksumlens(void) |
878 { | 879 { |
879 int i, j, n; | 880 int i, j, n; |
880 static size_t *cklens = NULL; | 881 static size_t *cklens = NULL; |
881 | 882 |
882 #ifdef KRB5_MIT_OLD11 | 883 #ifdef KRB5_MIT_OLD11 |
883 n = krb5_max_cksum; | 884 n = krb5_max_cksum; |
884 #else | 885 #else |
885 n = 0x0010; | 886 n = 0x0010; |
886 #endif /* KRB5_MIT_OLD11 */ | 887 #endif /* KRB5_MIT_OLD11 */ |
887 | 888 |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 printf("%02x",keyblk->contents[i]); | 1019 printf("%02x",keyblk->contents[i]); |
1019 } | 1020 } |
1020 printf("\n"); | 1021 printf("\n"); |
1021 #endif | 1022 #endif |
1022 } | 1023 } |
1023 | 1024 |
1024 | 1025 |
1025 /* Display contents of krb5_principal_data struct, for debugging | 1026 /* Display contents of krb5_principal_data struct, for debugging |
1026 ** (krb5_principal is typedef'd == krb5_principal_data *) | 1027 ** (krb5_principal is typedef'd == krb5_principal_data *) |
1027 */ | 1028 */ |
1028 void | 1029 static void |
1029 print_krb5_princ(char *label, krb5_principal_data *princ) | 1030 print_krb5_princ(char *label, krb5_principal_data *princ) |
1030 { | 1031 { |
1031 int i, ui, uj; | 1032 int i, ui, uj; |
1032 | 1033 |
1033 printf("%s principal Realm: ", label); | 1034 printf("%s principal Realm: ", label); |
1034 if (princ == NULL) return; | 1035 if (princ == NULL) return; |
1035 for (ui=0; ui < (int)princ->realm.length; ui++) putchar(princ->realm.da
ta[ui]); | 1036 for (ui=0; ui < (int)princ->realm.length; ui++) putchar(princ->realm.da
ta[ui]); |
1036 printf(" (nametype %d) has %d strings:\n", princ->type,princ->length); | 1037 printf(" (nametype %d) has %d strings:\n", princ->type,princ->length); |
1037 for (i=0; i < (int)princ->length; i++) | 1038 for (i=0; i < (int)princ->length; i++) |
1038 { | 1039 { |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1217 ** Return Kerberos error code and kssl_err struct on error. | 1218 ** Return Kerberos error code and kssl_err struct on error. |
1218 ** Allocates krb5_ticket and krb5_principal; caller should free these. | 1219 ** Allocates krb5_ticket and krb5_principal; caller should free these. |
1219 ** | 1220 ** |
1220 ** 20010410 VRS Implemented krb5_decode_ticket() as | 1221 ** 20010410 VRS Implemented krb5_decode_ticket() as |
1221 ** old_krb5_decode_ticket(). Missing from MIT1.0.6. | 1222 ** old_krb5_decode_ticket(). Missing from MIT1.0.6. |
1222 ** 20010615 VRS Re-cast as openssl/asn1 d2i_*() functions. | 1223 ** 20010615 VRS Re-cast as openssl/asn1 d2i_*() functions. |
1223 ** Re-used some of the old krb5_decode_ticket() | 1224 ** Re-used some of the old krb5_decode_ticket() |
1224 ** code here. This tkt should alloc/free just | 1225 ** code here. This tkt should alloc/free just |
1225 ** like the real thing. | 1226 ** like the real thing. |
1226 */ | 1227 */ |
1227 krb5_error_code | 1228 static krb5_error_code |
1228 kssl_TKT2tkt( /* IN */ krb5_context krb5context, | 1229 kssl_TKT2tkt( /* IN */ krb5_context krb5context, |
1229 /* IN */ KRB5_TKTBODY *asn1ticket, | 1230 /* IN */ KRB5_TKTBODY *asn1ticket, |
1230 /* OUT */ krb5_ticket **krb5ticket, | 1231 /* OUT */ krb5_ticket **krb5ticket, |
1231 /* OUT */ KSSL_ERR *kssl_err ) | 1232 /* OUT */ KSSL_ERR *kssl_err ) |
1232 { | 1233 { |
1233 krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; | 1234 krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; |
1234 krb5_ticket *new5ticket = NULL; | 1235 krb5_ticket *new5ticket = NULL; |
1235 ASN1_GENERALSTRING *gstr_svc, *gstr_host; | 1236 ASN1_GENERALSTRING *gstr_svc, *gstr_host; |
1236 | 1237 |
1237 *krb5ticket = NULL; | 1238 *krb5ticket = NULL; |
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1895 #endif /* !OPENSSL_SYS_WINDOWS && !OPENSSL_SYS_WIN32 */ | 1896 #endif /* !OPENSSL_SYS_WINDOWS && !OPENSSL_SYS_WIN32 */ |
1896 | 1897 |
1897 | 1898 |
1898 /* Given pointers to KerberosTime and struct tm structs, convert the | 1899 /* Given pointers to KerberosTime and struct tm structs, convert the |
1899 ** KerberosTime string to struct tm. Note that KerberosTime is a | 1900 ** KerberosTime string to struct tm. Note that KerberosTime is a |
1900 ** ASN1_GENERALIZEDTIME value, constrained to GMT with no fractional | 1901 ** ASN1_GENERALIZEDTIME value, constrained to GMT with no fractional |
1901 ** seconds as defined in RFC 1510. | 1902 ** seconds as defined in RFC 1510. |
1902 ** Return pointer to the (partially) filled in struct tm on success, | 1903 ** Return pointer to the (partially) filled in struct tm on success, |
1903 ** return NULL on failure. | 1904 ** return NULL on failure. |
1904 */ | 1905 */ |
1905 struct tm» *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) | 1906 static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) |
1906 { | 1907 { |
1907 char c, *p; | 1908 char c, *p; |
1908 | 1909 |
1909 if (!k_tm) return NULL; | 1910 if (!k_tm) return NULL; |
1910 if (gtime == NULL || gtime->length < 14) return NULL; | 1911 if (gtime == NULL || gtime->length < 14) return NULL; |
1911 if (gtime->data == NULL) return NULL; | 1912 if (gtime->data == NULL) return NULL; |
1912 | 1913 |
1913 p = (char *)>ime->data[14]; | 1914 p = (char *)>ime->data[14]; |
1914 | 1915 |
1915 c = *p; *p = '\0'; p -= 2; k_tm->tm_sec = atoi(p); *(p+2) = c; | 1916 c = *p; *p = '\0'; p -= 2; k_tm->tm_sec = atoi(p); *(p+2) = c; |
1916 c = *p; *p = '\0'; p -= 2; k_tm->tm_min = atoi(p); *(p+2) = c; | 1917 c = *p; *p = '\0'; p -= 2; k_tm->tm_min = atoi(p); *(p+2) = c; |
1917 c = *p; *p = '\0'; p -= 2; k_tm->tm_hour = atoi(p); *(p+2) = c; | 1918 c = *p; *p = '\0'; p -= 2; k_tm->tm_hour = atoi(p); *(p+2) = c; |
1918 c = *p; *p = '\0'; p -= 2; k_tm->tm_mday = atoi(p); *(p+2) = c; | 1919 c = *p; *p = '\0'; p -= 2; k_tm->tm_mday = atoi(p); *(p+2) = c; |
1919 c = *p; *p = '\0'; p -= 2; k_tm->tm_mon = atoi(p)-1; *(p+2) = c; | 1920 c = *p; *p = '\0'; p -= 2; k_tm->tm_mon = atoi(p)-1; *(p+2) = c; |
1920 c = *p; *p = '\0'; p -= 4; k_tm->tm_year = atoi(p)-1900; *(p+4) = c; | 1921 c = *p; *p = '\0'; p -= 4; k_tm->tm_year = atoi(p)-1900; *(p+4) = c; |
1921 | 1922 |
1922 return k_tm; | 1923 return k_tm; |
1923 } | 1924 } |
1924 | 1925 |
1925 | 1926 |
1926 /* Helper function for kssl_validate_times(). | 1927 /* Helper function for kssl_validate_times(). |
1927 ** We need context->clockskew, but krb5_context is an opaque struct. | 1928 ** We need context->clockskew, but krb5_context is an opaque struct. |
1928 ** So we try to sneek the clockskew out through the replay cache. | 1929 ** So we try to sneek the clockskew out through the replay cache. |
1929 ** If that fails just return a likely default (300 seconds). | 1930 ** If that fails just return a likely default (300 seconds). |
1930 */ | 1931 */ |
1931 krb5_deltat» get_rc_clockskew(krb5_context context) | 1932 static krb5_deltat get_rc_clockskew(krb5_context context) |
1932 { | 1933 { |
1933 krb5_rcache rc; | 1934 krb5_rcache rc; |
1934 krb5_deltat clockskew; | 1935 krb5_deltat clockskew; |
1935 | 1936 |
1936 if (krb5_rc_default(context, &rc)) return KSSL_CLOCKSKEW; | 1937 if (krb5_rc_default(context, &rc)) return KSSL_CLOCKSKEW; |
1937 if (krb5_rc_initialize(context, rc, 0)) return KSSL_CLOCKSKEW; | 1938 if (krb5_rc_initialize(context, rc, 0)) return KSSL_CLOCKSKEW; |
1938 if (krb5_rc_get_lifespan(context, rc, &clockskew)) { | 1939 if (krb5_rc_get_lifespan(context, rc, &clockskew)) { |
1939 clockskew = KSSL_CLOCKSKEW; | 1940 clockskew = KSSL_CLOCKSKEW; |
1940 } | 1941 } |
1941 (void) krb5_rc_destroy(context, rc); | 1942 (void) krb5_rc_destroy(context, rc); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2085 if (!EVP_Cipher(&ciph_ctx,unenc_authent,dec_authent->cipher->data,outl)) | 2086 if (!EVP_Cipher(&ciph_ctx,unenc_authent,dec_authent->cipher->data,outl)) |
2086 { | 2087 { |
2087 kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 2088 kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
2088 "EVP_Cipher error decrypting authenticator.\n"); | 2089 "EVP_Cipher error decrypting authenticator.\n"); |
2089 krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; | 2090 krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; |
2090 goto err; | 2091 goto err; |
2091 } | 2092 } |
2092 EVP_CIPHER_CTX_cleanup(&ciph_ctx); | 2093 EVP_CIPHER_CTX_cleanup(&ciph_ctx); |
2093 | 2094 |
2094 #ifdef KSSL_DEBUG | 2095 #ifdef KSSL_DEBUG |
| 2096 { |
| 2097 int padl; |
2095 printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl); | 2098 printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl); |
2096 for (padl=0; padl < outl; padl++) printf("%02x ",unenc_authent[padl]); | 2099 for (padl=0; padl < outl; padl++) printf("%02x ",unenc_authent[padl]); |
2097 printf("\n"); | 2100 printf("\n"); |
| 2101 } |
2098 #endif /* KSSL_DEBUG */ | 2102 #endif /* KSSL_DEBUG */ |
2099 | 2103 |
2100 if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL) | 2104 if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL) |
2101 { | 2105 { |
2102 kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 2106 kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
2103 "confounded by authenticator.\n"); | 2107 "confounded by authenticator.\n"); |
2104 krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; | 2108 krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; |
2105 goto err; | 2109 goto err; |
2106 } | 2110 } |
2107 outl -= p - unenc_authent; | 2111 outl -= p - unenc_authent; |
2108 | 2112 |
2109 if ((auth = (KRB5_AUTHENTBODY *) d2i_KRB5_AUTHENT(NULL, &p, | 2113 if ((auth = (KRB5_AUTHENTBODY *) d2i_KRB5_AUTHENT(NULL, &p, |
2110 (long) outl))==NULL) | 2114 (long) outl))==NULL) |
2111 { | 2115 { |
2112 kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, | 2116 kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, |
2113 "Error decoding authenticator body.\n"); | 2117 "Error decoding authenticator body.\n"); |
2114 krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; | 2118 krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; |
2115 goto err; | 2119 goto err; |
2116 } | 2120 } |
2117 | 2121 |
2118 memset(&tm_time,0,sizeof(struct tm)); | 2122 memset(&tm_time,0,sizeof(struct tm)); |
2119 if (k_gmtime(auth->ctime, &tm_time) && | 2123 if (k_gmtime(auth->ctime, &tm_time) && |
2120 ((tr = mktime(&tm_time)) != (time_t)(-1))) | 2124 ((tr = mktime(&tm_time)) != (time_t)(-1))) |
2121 { | 2125 { |
2122 now = time(&now); | 2126 now = time(&now); |
2123 tm_l = localtime(&now); tl = mktime(tm_l); | 2127 tm_l = localtime(&now); tl = mktime(tm_l); |
2124 tm_g = gmtime(&now); tg = mktime(tm_g); | 2128 tm_g = gmtime(&now); tg = mktime(tm_g); |
2125 tz_offset = tg - tl; | 2129 tz_offset = tg - tl; |
2126 | 2130 |
2127 » » *atimep = tr - tz_offset; | 2131 » » *atimep = (krb5_timestamp)(tr - tz_offset); |
2128 } | 2132 } |
2129 | 2133 |
2130 #ifdef KSSL_DEBUG | 2134 #ifdef KSSL_DEBUG |
2131 printf("kssl_check_authent: returns %d for client time ", *atimep); | 2135 printf("kssl_check_authent: returns %d for client time ", *atimep); |
2132 if (auth && auth->ctime && auth->ctime->length && auth->ctime->data) | 2136 if (auth && auth->ctime && auth->ctime->length && auth->ctime->data) |
2133 printf("%.*s\n", auth->ctime->length, auth->ctime->data); | 2137 printf("%.*s\n", auth->ctime->length, auth->ctime->data); |
2134 else printf("NULL\n"); | 2138 else printf("NULL\n"); |
2135 #endif /* KSSL_DEBUG */ | 2139 #endif /* KSSL_DEBUG */ |
2136 | 2140 |
2137 err: | 2141 err: |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2192 | 2196 |
2193 | 2197 |
2194 #else /* !OPENSSL_NO_KRB5 */ | 2198 #else /* !OPENSSL_NO_KRB5 */ |
2195 | 2199 |
2196 #if defined(PEDANTIC) || defined(OPENSSL_SYS_VMS) | 2200 #if defined(PEDANTIC) || defined(OPENSSL_SYS_VMS) |
2197 static void *dummy=&dummy; | 2201 static void *dummy=&dummy; |
2198 #endif | 2202 #endif |
2199 | 2203 |
2200 #endif /* !OPENSSL_NO_KRB5 */ | 2204 #endif /* !OPENSSL_NO_KRB5 */ |
2201 | 2205 |
OLD | NEW |