aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/auth_gss/gss_krb5_unseal.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/auth_gss/gss_krb5_unseal.c')
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_unseal.c113
1 files changed, 101 insertions, 12 deletions
diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c
index ce6c247edad0..6cd930f3678f 100644
--- a/net/sunrpc/auth_gss/gss_krb5_unseal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/k5unseal.c 4 * Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/k5unseal.c
5 * 5 *
6 * Copyright (c) 2000 The Regents of the University of Michigan. 6 * Copyright (c) 2000-2008 The Regents of the University of Michigan.
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Andy Adamson <andros@umich.edu> 9 * Andy Adamson <andros@umich.edu>
@@ -70,20 +70,21 @@
70/* read_token is a mic token, and message_buffer is the data that the mic was 70/* read_token is a mic token, and message_buffer is the data that the mic was
71 * supposedly taken over. */ 71 * supposedly taken over. */
72 72
73u32 73static u32
74gss_verify_mic_kerberos(struct gss_ctx *gss_ctx, 74gss_verify_mic_v1(struct krb5_ctx *ctx,
75 struct xdr_buf *message_buffer, struct xdr_netobj *read_token) 75 struct xdr_buf *message_buffer, struct xdr_netobj *read_token)
76{ 76{
77 struct krb5_ctx *ctx = gss_ctx->internal_ctx_id;
78 int signalg; 77 int signalg;
79 int sealalg; 78 int sealalg;
80 char cksumdata[16]; 79 char cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
81 struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; 80 struct xdr_netobj md5cksum = {.len = sizeof(cksumdata),
81 .data = cksumdata};
82 s32 now; 82 s32 now;
83 int direction; 83 int direction;
84 u32 seqnum; 84 u32 seqnum;
85 unsigned char *ptr = (unsigned char *)read_token->data; 85 unsigned char *ptr = (unsigned char *)read_token->data;
86 int bodysize; 86 int bodysize;
87 u8 *cksumkey;
87 88
88 dprintk("RPC: krb5_read_token\n"); 89 dprintk("RPC: krb5_read_token\n");
89 90
@@ -98,7 +99,7 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
98 /* XXX sanity-check bodysize?? */ 99 /* XXX sanity-check bodysize?? */
99 100
100 signalg = ptr[2] + (ptr[3] << 8); 101 signalg = ptr[2] + (ptr[3] << 8);
101 if (signalg != SGN_ALG_DES_MAC_MD5) 102 if (signalg != ctx->gk5e->signalg)
102 return GSS_S_DEFECTIVE_TOKEN; 103 return GSS_S_DEFECTIVE_TOKEN;
103 104
104 sealalg = ptr[4] + (ptr[5] << 8); 105 sealalg = ptr[4] + (ptr[5] << 8);
@@ -108,13 +109,17 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
108 if ((ptr[6] != 0xff) || (ptr[7] != 0xff)) 109 if ((ptr[6] != 0xff) || (ptr[7] != 0xff))
109 return GSS_S_DEFECTIVE_TOKEN; 110 return GSS_S_DEFECTIVE_TOKEN;
110 111
111 if (make_checksum("md5", ptr, 8, message_buffer, 0, &md5cksum)) 112 if (ctx->gk5e->keyed_cksum)
112 return GSS_S_FAILURE; 113 cksumkey = ctx->cksum;
114 else
115 cksumkey = NULL;
113 116
114 if (krb5_encrypt(ctx->seq, NULL, md5cksum.data, md5cksum.data, 16)) 117 if (make_checksum(ctx, ptr, 8, message_buffer, 0,
118 cksumkey, KG_USAGE_SIGN, &md5cksum))
115 return GSS_S_FAILURE; 119 return GSS_S_FAILURE;
116 120
117 if (memcmp(md5cksum.data + 8, ptr + GSS_KRB5_TOK_HDR_LEN, 8)) 121 if (memcmp(md5cksum.data, ptr + GSS_KRB5_TOK_HDR_LEN,
122 ctx->gk5e->cksumlength))
118 return GSS_S_BAD_SIG; 123 return GSS_S_BAD_SIG;
119 124
120 /* it got through unscathed. Make sure the context is unexpired */ 125 /* it got through unscathed. Make sure the context is unexpired */
@@ -126,7 +131,8 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
126 131
127 /* do sequencing checks */ 132 /* do sequencing checks */
128 133
129 if (krb5_get_seq_num(ctx->seq, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8, &direction, &seqnum)) 134 if (krb5_get_seq_num(ctx, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8,
135 &direction, &seqnum))
130 return GSS_S_FAILURE; 136 return GSS_S_FAILURE;
131 137
132 if ((ctx->initiate && direction != 0xff) || 138 if ((ctx->initiate && direction != 0xff) ||
@@ -135,3 +141,86 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
135 141
136 return GSS_S_COMPLETE; 142 return GSS_S_COMPLETE;
137} 143}
144
145static u32
146gss_verify_mic_v2(struct krb5_ctx *ctx,
147 struct xdr_buf *message_buffer, struct xdr_netobj *read_token)
148{
149 char cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
150 struct xdr_netobj cksumobj = {.len = sizeof(cksumdata),
151 .data = cksumdata};
152 s32 now;
153 u64 seqnum;
154 u8 *ptr = read_token->data;
155 u8 *cksumkey;
156 u8 flags;
157 int i;
158 unsigned int cksum_usage;
159
160 dprintk("RPC: %s\n", __func__);
161
162 if (be16_to_cpu(*((__be16 *)ptr)) != KG2_TOK_MIC)
163 return GSS_S_DEFECTIVE_TOKEN;
164
165 flags = ptr[2];
166 if ((!ctx->initiate && (flags & KG2_TOKEN_FLAG_SENTBYACCEPTOR)) ||
167 (ctx->initiate && !(flags & KG2_TOKEN_FLAG_SENTBYACCEPTOR)))
168 return GSS_S_BAD_SIG;
169
170 if (flags & KG2_TOKEN_FLAG_SEALED) {
171 dprintk("%s: token has unexpected sealed flag\n", __func__);
172 return GSS_S_FAILURE;
173 }
174
175 for (i = 3; i < 8; i++)
176 if (ptr[i] != 0xff)
177 return GSS_S_DEFECTIVE_TOKEN;
178
179 if (ctx->initiate) {
180 cksumkey = ctx->acceptor_sign;
181 cksum_usage = KG_USAGE_ACCEPTOR_SIGN;
182 } else {
183 cksumkey = ctx->initiator_sign;
184 cksum_usage = KG_USAGE_INITIATOR_SIGN;
185 }
186
187 if (make_checksum_v2(ctx, ptr, GSS_KRB5_TOK_HDR_LEN, message_buffer, 0,
188 cksumkey, cksum_usage, &cksumobj))
189 return GSS_S_FAILURE;
190
191 if (memcmp(cksumobj.data, ptr + GSS_KRB5_TOK_HDR_LEN,
192 ctx->gk5e->cksumlength))
193 return GSS_S_BAD_SIG;
194
195 /* it got through unscathed. Make sure the context is unexpired */
196 now = get_seconds();
197 if (now > ctx->endtime)
198 return GSS_S_CONTEXT_EXPIRED;
199
200 /* do sequencing checks */
201
202 seqnum = be64_to_cpup((__be64 *)ptr + 8);
203
204 return GSS_S_COMPLETE;
205}
206
207u32
208gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
209 struct xdr_buf *message_buffer,
210 struct xdr_netobj *read_token)
211{
212 struct krb5_ctx *ctx = gss_ctx->internal_ctx_id;
213
214 switch (ctx->enctype) {
215 default:
216 BUG();
217 case ENCTYPE_DES_CBC_RAW:
218 case ENCTYPE_DES3_CBC_RAW:
219 case ENCTYPE_ARCFOUR_HMAC:
220 return gss_verify_mic_v1(ctx, message_buffer, read_token);
221 case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
222 case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
223 return gss_verify_mic_v2(ctx, message_buffer, read_token);
224 }
225}
226