aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sunrpc/gss_spkm3.h34
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c2
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_mech.c131
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_seal.c101
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_token.c6
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_unseal.c88
6 files changed, 180 insertions, 182 deletions
diff --git a/include/linux/sunrpc/gss_spkm3.h b/include/linux/sunrpc/gss_spkm3.h
index 2cf3fbb40b4f..e3e6a3437f8b 100644
--- a/include/linux/sunrpc/gss_spkm3.h
+++ b/include/linux/sunrpc/gss_spkm3.h
@@ -12,27 +12,19 @@
12#include <linux/sunrpc/gss_asn1.h> 12#include <linux/sunrpc/gss_asn1.h>
13 13
14struct spkm3_ctx { 14struct spkm3_ctx {
15 struct xdr_netobj ctx_id; /* per message context id */ 15 struct xdr_netobj ctx_id; /* per message context id */
16 int qop; /* negotiated qop */ 16 int endtime; /* endtime of the context */
17 struct xdr_netobj mech_used; 17 struct xdr_netobj mech_used;
18 unsigned int ret_flags ; 18 unsigned int ret_flags ;
19 unsigned int req_flags ; 19 struct xdr_netobj conf_alg;
20 struct xdr_netobj share_key; 20 struct xdr_netobj derived_conf_key;
21 int conf_alg; 21 struct xdr_netobj intg_alg;
22 struct crypto_blkcipher *derived_conf_key; 22 struct xdr_netobj derived_integ_key;
23 int intg_alg;
24 struct crypto_blkcipher *derived_integ_key;
25 int keyestb_alg; /* alg used to get share_key */
26 int owf_alg; /* one way function */
27}; 23};
28 24
29/* from openssl/objects.h */ 25/* OIDs declarations for K-ALG, I-ALG, C-ALG, and OWF-ALG */
30/* XXX need SEAL_ALG_NONE */ 26extern const struct xdr_netobj hmac_md5_oid;
31#define NID_md5 4 27extern const struct xdr_netobj cast5_cbc_oid;
32#define NID_dhKeyAgreement 28
33#define NID_des_cbc 31
34#define NID_sha1 64
35#define NID_cast5_cbc 108
36 28
37/* SPKM InnerContext Token types */ 29/* SPKM InnerContext Token types */
38 30
@@ -46,11 +38,13 @@ u32 spkm3_make_token(struct spkm3_ctx *ctx, struct xdr_buf * text, struct xdr_ne
46u32 spkm3_read_token(struct spkm3_ctx *ctx, struct xdr_netobj *read_token, struct xdr_buf *message_buffer, int toktype); 38u32 spkm3_read_token(struct spkm3_ctx *ctx, struct xdr_netobj *read_token, struct xdr_buf *message_buffer, int toktype);
47 39
48#define CKSUMTYPE_RSA_MD5 0x0007 40#define CKSUMTYPE_RSA_MD5 0x0007
41#define CKSUMTYPE_HMAC_MD5 0x0008
49 42
50s32 make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, 43s32 make_spkm3_checksum(s32 cksumtype, struct xdr_netobj *key, char *header,
51 int body_offset, struct xdr_netobj *cksum); 44 unsigned int hdrlen, struct xdr_buf *body,
45 unsigned int body_offset, struct xdr_netobj *cksum);
52void asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits); 46void asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits);
53int decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, 47int decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen,
54 int explen); 48 int explen);
55void spkm3_mic_header(unsigned char **hdrbuf, unsigned int *hdrlen, 49void spkm3_mic_header(unsigned char **hdrbuf, unsigned int *hdrlen,
56 unsigned char *ctxhdr, int elen, int zbit); 50 unsigned char *ctxhdr, int elen, int zbit);
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index d12ee5f54c0c..a02ecc1f230d 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -68,7 +68,7 @@ static struct rpc_credops gss_credops;
68#define GSS_CRED_SLACK 1024 /* XXX: unused */ 68#define GSS_CRED_SLACK 1024 /* XXX: unused */
69/* length of a krb5 verifier (48), plus data added before arguments when 69/* length of a krb5 verifier (48), plus data added before arguments when
70 * using integrity (two 4-byte integers): */ 70 * using integrity (two 4-byte integers): */
71#define GSS_VERF_SLACK 56 71#define GSS_VERF_SLACK 100
72 72
73/* XXX this define must match the gssd define 73/* XXX this define must match the gssd define
74* as it is passed to gssd to signal the use of 74* as it is passed to gssd to signal the use of
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
index d57f60838895..41465072d0b5 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_mech.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c
@@ -82,133 +82,73 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
82 return q; 82 return q;
83} 83}
84 84
85static inline const void *
86get_key(const void *p, const void *end, struct crypto_blkcipher **res,
87 int *resalg)
88{
89 struct xdr_netobj key = { 0 };
90 int setkey = 0;
91 char *alg_name;
92
93 p = simple_get_bytes(p, end, resalg, sizeof(*resalg));
94 if (IS_ERR(p))
95 goto out_err;
96 p = simple_get_netobj(p, end, &key);
97 if (IS_ERR(p))
98 goto out_err;
99
100 switch (*resalg) {
101 case NID_des_cbc:
102 alg_name = "cbc(des)";
103 setkey = 1;
104 break;
105 case NID_cast5_cbc:
106 /* XXXX here in name only, not used */
107 alg_name = "cbc(cast5)";
108 setkey = 0; /* XXX will need to set to 1 */
109 break;
110 case NID_md5:
111 if (key.len == 0) {
112 dprintk("RPC: SPKM3 get_key: NID_md5 zero Key length\n");
113 }
114 alg_name = "md5";
115 setkey = 0;
116 break;
117 default:
118 dprintk("gss_spkm3_mech: unsupported algorithm %d\n", *resalg);
119 goto out_err_free_key;
120 }
121 *res = crypto_alloc_blkcipher(alg_name, 0, CRYPTO_ALG_ASYNC);
122 if (IS_ERR(*res)) {
123 printk("gss_spkm3_mech: unable to initialize crypto algorthm %s\n", alg_name);
124 *res = NULL;
125 goto out_err_free_key;
126 }
127 if (setkey) {
128 if (crypto_blkcipher_setkey(*res, key.data, key.len)) {
129 printk("gss_spkm3_mech: error setting key for crypto algorthm %s\n", alg_name);
130 goto out_err_free_tfm;
131 }
132 }
133
134 if(key.len > 0)
135 kfree(key.data);
136 return p;
137
138out_err_free_tfm:
139 crypto_free_blkcipher(*res);
140out_err_free_key:
141 if(key.len > 0)
142 kfree(key.data);
143 p = ERR_PTR(-EINVAL);
144out_err:
145 return p;
146}
147
148static int 85static int
149gss_import_sec_context_spkm3(const void *p, size_t len, 86gss_import_sec_context_spkm3(const void *p, size_t len,
150 struct gss_ctx *ctx_id) 87 struct gss_ctx *ctx_id)
151{ 88{
152 const void *end = (const void *)((const char *)p + len); 89 const void *end = (const void *)((const char *)p + len);
153 struct spkm3_ctx *ctx; 90 struct spkm3_ctx *ctx;
91 int version;
154 92
155 if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL))) 93 if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL)))
156 goto out_err; 94 goto out_err;
157 95
96 p = simple_get_bytes(p, end, &version, sizeof(version));
97 if (IS_ERR(p))
98 goto out_err_free_ctx;
99 if (version != 1) {
100 dprintk("RPC: unknown spkm3 token format: obsolete nfs-utils?\n");
101 goto out_err_free_ctx;
102 }
103
158 p = simple_get_netobj(p, end, &ctx->ctx_id); 104 p = simple_get_netobj(p, end, &ctx->ctx_id);
159 if (IS_ERR(p)) 105 if (IS_ERR(p))
160 goto out_err_free_ctx; 106 goto out_err_free_ctx;
161 107
162 p = simple_get_bytes(p, end, &ctx->qop, sizeof(ctx->qop)); 108 p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime));
163 if (IS_ERR(p)) 109 if (IS_ERR(p))
164 goto out_err_free_ctx_id; 110 goto out_err_free_ctx_id;
165 111
166 p = simple_get_netobj(p, end, &ctx->mech_used); 112 p = simple_get_netobj(p, end, &ctx->mech_used);
167 if (IS_ERR(p)) 113 if (IS_ERR(p))
168 goto out_err_free_mech; 114 goto out_err_free_ctx_id;
169 115
170 p = simple_get_bytes(p, end, &ctx->ret_flags, sizeof(ctx->ret_flags)); 116 p = simple_get_bytes(p, end, &ctx->ret_flags, sizeof(ctx->ret_flags));
171 if (IS_ERR(p)) 117 if (IS_ERR(p))
172 goto out_err_free_mech; 118 goto out_err_free_mech;
173 119
174 p = simple_get_bytes(p, end, &ctx->req_flags, sizeof(ctx->req_flags)); 120 p = simple_get_netobj(p, end, &ctx->conf_alg);
175 if (IS_ERR(p)) 121 if (IS_ERR(p))
176 goto out_err_free_mech; 122 goto out_err_free_mech;
177 123
178 p = simple_get_netobj(p, end, &ctx->share_key); 124 p = simple_get_netobj(p, end, &ctx->derived_conf_key);
179 if (IS_ERR(p))
180 goto out_err_free_s_key;
181
182 p = get_key(p, end, &ctx->derived_conf_key, &ctx->conf_alg);
183 if (IS_ERR(p)) 125 if (IS_ERR(p))
184 goto out_err_free_s_key; 126 goto out_err_free_conf_alg;
185 127
186 p = get_key(p, end, &ctx->derived_integ_key, &ctx->intg_alg); 128 p = simple_get_netobj(p, end, &ctx->intg_alg);
187 if (IS_ERR(p)) 129 if (IS_ERR(p))
188 goto out_err_free_key1; 130 goto out_err_free_conf_key;
189 131
190 p = simple_get_bytes(p, end, &ctx->keyestb_alg, sizeof(ctx->keyestb_alg)); 132 p = simple_get_netobj(p, end, &ctx->derived_integ_key);
191 if (IS_ERR(p)) 133 if (IS_ERR(p))
192 goto out_err_free_key2; 134 goto out_err_free_intg_alg;
193
194 p = simple_get_bytes(p, end, &ctx->owf_alg, sizeof(ctx->owf_alg));
195 if (IS_ERR(p))
196 goto out_err_free_key2;
197 135
198 if (p != end) 136 if (p != end)
199 goto out_err_free_key2; 137 goto out_err_free_intg_key;
200 138
201 ctx_id->internal_ctx_id = ctx; 139 ctx_id->internal_ctx_id = ctx;
202 140
203 dprintk("Successfully imported new spkm context.\n"); 141 dprintk("Successfully imported new spkm context.\n");
204 return 0; 142 return 0;
205 143
206out_err_free_key2: 144out_err_free_intg_key:
207 crypto_free_blkcipher(ctx->derived_integ_key); 145 kfree(ctx->derived_integ_key.data);
208out_err_free_key1: 146out_err_free_intg_alg:
209 crypto_free_blkcipher(ctx->derived_conf_key); 147 kfree(ctx->intg_alg.data);
210out_err_free_s_key: 148out_err_free_conf_key:
211 kfree(ctx->share_key.data); 149 kfree(ctx->derived_conf_key.data);
150out_err_free_conf_alg:
151 kfree(ctx->conf_alg.data);
212out_err_free_mech: 152out_err_free_mech:
213 kfree(ctx->mech_used.data); 153 kfree(ctx->mech_used.data);
214out_err_free_ctx_id: 154out_err_free_ctx_id:
@@ -220,13 +160,16 @@ out_err:
220} 160}
221 161
222static void 162static void
223gss_delete_sec_context_spkm3(void *internal_ctx) { 163gss_delete_sec_context_spkm3(void *internal_ctx)
164{
224 struct spkm3_ctx *sctx = internal_ctx; 165 struct spkm3_ctx *sctx = internal_ctx;
225 166
226 crypto_free_blkcipher(sctx->derived_integ_key); 167 kfree(sctx->derived_integ_key.data);
227 crypto_free_blkcipher(sctx->derived_conf_key); 168 kfree(sctx->intg_alg.data);
228 kfree(sctx->share_key.data); 169 kfree(sctx->derived_conf_key.data);
170 kfree(sctx->conf_alg.data);
229 kfree(sctx->mech_used.data); 171 kfree(sctx->mech_used.data);
172 kfree(sctx->ctx_id.data);
230 kfree(sctx); 173 kfree(sctx);
231} 174}
232 175
@@ -238,7 +181,6 @@ gss_verify_mic_spkm3(struct gss_ctx *ctx,
238 u32 maj_stat = 0; 181 u32 maj_stat = 0;
239 struct spkm3_ctx *sctx = ctx->internal_ctx_id; 182 struct spkm3_ctx *sctx = ctx->internal_ctx_id;
240 183
241 dprintk("RPC: gss_verify_mic_spkm3 calling spkm3_read_token\n");
242 maj_stat = spkm3_read_token(sctx, checksum, signbuf, SPKM_MIC_TOK); 184 maj_stat = spkm3_read_token(sctx, checksum, signbuf, SPKM_MIC_TOK);
243 185
244 dprintk("RPC: gss_verify_mic_spkm3 returning %d\n", maj_stat); 186 dprintk("RPC: gss_verify_mic_spkm3 returning %d\n", maj_stat);
@@ -253,10 +195,9 @@ gss_get_mic_spkm3(struct gss_ctx *ctx,
253 u32 err = 0; 195 u32 err = 0;
254 struct spkm3_ctx *sctx = ctx->internal_ctx_id; 196 struct spkm3_ctx *sctx = ctx->internal_ctx_id;
255 197
256 dprintk("RPC: gss_get_mic_spkm3\n");
257
258 err = spkm3_make_token(sctx, message_buffer, 198 err = spkm3_make_token(sctx, message_buffer,
259 message_token, SPKM_MIC_TOK); 199 message_token, SPKM_MIC_TOK);
200 dprintk("RPC: gss_get_mic_spkm3 returning %d\n", err);
260 return err; 201 return err;
261} 202}
262 203
diff --git a/net/sunrpc/auth_gss/gss_spkm3_seal.c b/net/sunrpc/auth_gss/gss_spkm3_seal.c
index 18c7862bc234..b179d58c6249 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_seal.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_seal.c
@@ -39,11 +39,17 @@
39#include <linux/sunrpc/gss_spkm3.h> 39#include <linux/sunrpc/gss_spkm3.h>
40#include <linux/random.h> 40#include <linux/random.h>
41#include <linux/crypto.h> 41#include <linux/crypto.h>
42#include <linux/pagemap.h>
43#include <linux/scatterlist.h>
44#include <linux/sunrpc/xdr.h>
42 45
43#ifdef RPC_DEBUG 46#ifdef RPC_DEBUG
44# define RPCDBG_FACILITY RPCDBG_AUTH 47# define RPCDBG_FACILITY RPCDBG_AUTH
45#endif 48#endif
46 49
50const struct xdr_netobj hmac_md5_oid = { 8, "\x2B\x06\x01\x05\x05\x08\x01\x01"};
51const struct xdr_netobj cast5_cbc_oid = {9, "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0A"};
52
47/* 53/*
48 * spkm3_make_token() 54 * spkm3_make_token()
49 * 55 *
@@ -66,29 +72,23 @@ spkm3_make_token(struct spkm3_ctx *ctx,
66 int ctxelen = 0, ctxzbit = 0; 72 int ctxelen = 0, ctxzbit = 0;
67 int md5elen = 0, md5zbit = 0; 73 int md5elen = 0, md5zbit = 0;
68 74
69 dprintk("RPC: spkm3_make_token\n");
70
71 now = jiffies; 75 now = jiffies;
72 76
73 if (ctx->ctx_id.len != 16) { 77 if (ctx->ctx_id.len != 16) {
74 dprintk("RPC: spkm3_make_token BAD ctx_id.len %d\n", 78 dprintk("RPC: spkm3_make_token BAD ctx_id.len %d\n",
75 ctx->ctx_id.len); 79 ctx->ctx_id.len);
76 goto out_err; 80 goto out_err;
77 } 81 }
78 82
79 switch (ctx->intg_alg) { 83 if (!g_OID_equal(&ctx->intg_alg, &hmac_md5_oid)) {
80 case NID_md5: 84 dprintk("RPC: gss_spkm3_seal: unsupported I-ALG algorithm."
81 checksum_type = CKSUMTYPE_RSA_MD5; 85 "only support hmac-md5 I-ALG.\n");
82 break; 86 goto out_err;
83 default: 87 } else
84 dprintk("RPC: gss_spkm3_seal: ctx->signalg %d not" 88 checksum_type = CKSUMTYPE_HMAC_MD5;
85 " supported\n", ctx->intg_alg); 89
86 goto out_err; 90 if (!g_OID_equal(&ctx->conf_alg, &cast5_cbc_oid)) {
87 } 91 dprintk("RPC: gss_spkm3_seal: unsupported C-ALG algorithm\n");
88 /* XXX since we don't support WRAP, perhaps we don't care... */
89 if (ctx->conf_alg != NID_cast5_cbc) {
90 dprintk("RPC: gss_spkm3_seal: ctx->sealalg %d not supported\n",
91 ctx->conf_alg);
92 goto out_err; 92 goto out_err;
93 } 93 }
94 94
@@ -96,10 +96,10 @@ spkm3_make_token(struct spkm3_ctx *ctx,
96 /* Calculate checksum over the mic-header */ 96 /* Calculate checksum over the mic-header */
97 asn1_bitstring_len(&ctx->ctx_id, &ctxelen, &ctxzbit); 97 asn1_bitstring_len(&ctx->ctx_id, &ctxelen, &ctxzbit);
98 spkm3_mic_header(&mic_hdr.data, &mic_hdr.len, ctx->ctx_id.data, 98 spkm3_mic_header(&mic_hdr.data, &mic_hdr.len, ctx->ctx_id.data,
99 ctxelen, ctxzbit); 99 ctxelen, ctxzbit);
100 100 if (make_spkm3_checksum(checksum_type, &ctx->derived_integ_key,
101 if (make_checksum(checksum_type, mic_hdr.data, mic_hdr.len, 101 (char *)mic_hdr.data, mic_hdr.len,
102 text, 0, &md5cksum)) 102 text, 0, &md5cksum))
103 goto out_err; 103 goto out_err;
104 104
105 asn1_bitstring_len(&md5cksum, &md5elen, &md5zbit); 105 asn1_bitstring_len(&md5cksum, &md5elen, &md5zbit);
@@ -121,7 +121,66 @@ spkm3_make_token(struct spkm3_ctx *ctx,
121 121
122 return GSS_S_COMPLETE; 122 return GSS_S_COMPLETE;
123out_err: 123out_err:
124 if (md5cksum.data)
125 kfree(md5cksum.data);
126
124 token->data = NULL; 127 token->data = NULL;
125 token->len = 0; 128 token->len = 0;
126 return GSS_S_FAILURE; 129 return GSS_S_FAILURE;
127} 130}
131
132static int
133spkm3_checksummer(struct scatterlist *sg, void *data)
134{
135 struct hash_desc *desc = data;
136
137 return crypto_hash_update(desc, sg, sg->length);
138}
139
140/* checksum the plaintext data and hdrlen bytes of the token header */
141s32
142make_spkm3_checksum(s32 cksumtype, struct xdr_netobj *key, char *header,
143 unsigned int hdrlen, struct xdr_buf *body,
144 unsigned int body_offset, struct xdr_netobj *cksum)
145{
146 char *cksumname;
147 struct hash_desc desc; /* XXX add to ctx? */
148 struct scatterlist sg[1];
149 int err;
150
151 switch (cksumtype) {
152 case CKSUMTYPE_HMAC_MD5:
153 cksumname = "md5";
154 break;
155 default:
156 dprintk("RPC: spkm3_make_checksum:"
157 " unsupported checksum %d", cksumtype);
158 return GSS_S_FAILURE;
159 }
160
161 if (key->data == NULL || key->len <= 0) return GSS_S_FAILURE;
162
163 desc.tfm = crypto_alloc_hash(cksumname, 0, CRYPTO_ALG_ASYNC);
164 if (IS_ERR(desc.tfm))
165 return GSS_S_FAILURE;
166 cksum->len = crypto_hash_digestsize(desc.tfm);
167 desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
168
169 err = crypto_hash_setkey(desc.tfm, key->data, key->len);
170 if (err)
171 goto out;
172
173 sg_set_buf(sg, header, hdrlen);
174 crypto_hash_update(&desc, sg, 1);
175
176 xdr_process_buf(body, body_offset, body->len - body_offset,
177 spkm3_checksummer, &desc);
178 crypto_hash_final(&desc, cksum->data);
179
180out:
181 crypto_free_hash(desc.tfm);
182
183 return err ? GSS_S_FAILURE : 0;
184}
185
186EXPORT_SYMBOL(make_spkm3_checksum);
diff --git a/net/sunrpc/auth_gss/gss_spkm3_token.c b/net/sunrpc/auth_gss/gss_spkm3_token.c
index 854a983ccf26..35188b6ea8f7 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_token.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_token.c
@@ -172,10 +172,10 @@ spkm3_mic_header(unsigned char **hdrbuf, unsigned int *hdrlen, unsigned char *ct
172 *(u8 *)hptr++ = zbit; 172 *(u8 *)hptr++ = zbit;
173 memcpy(hptr, ctxdata, elen); 173 memcpy(hptr, ctxdata, elen);
174 hptr += elen; 174 hptr += elen;
175 *hdrlen = hptr - top; 175 *hdrlen = hptr - top;
176} 176}
177 177
178/* 178/*
179 * spkm3_mic_innercontext_token() 179 * spkm3_mic_innercontext_token()
180 * 180 *
181 * *tokp points to the beginning of the SPKM_MIC token described 181 * *tokp points to the beginning of the SPKM_MIC token described
diff --git a/net/sunrpc/auth_gss/gss_spkm3_unseal.c b/net/sunrpc/auth_gss/gss_spkm3_unseal.c
index 544eb6fd9094..e54581ca7570 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_unseal.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_unseal.c
@@ -54,66 +54,70 @@ spkm3_read_token(struct spkm3_ctx *ctx,
54 struct xdr_buf *message_buffer, /* signbuf */ 54 struct xdr_buf *message_buffer, /* signbuf */
55 int toktype) 55 int toktype)
56{ 56{
57 s32 checksum_type;
57 s32 code; 58 s32 code;
58 struct xdr_netobj wire_cksum = {.len =0, .data = NULL}; 59 struct xdr_netobj wire_cksum = {.len =0, .data = NULL};
59 char cksumdata[16]; 60 char cksumdata[16];
60 struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; 61 struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata};
61 unsigned char *ptr = (unsigned char *)read_token->data; 62 unsigned char *ptr = (unsigned char *)read_token->data;
62 unsigned char *cksum; 63 unsigned char *cksum;
63 int bodysize, md5elen; 64 int bodysize, md5elen;
64 int mic_hdrlen; 65 int mic_hdrlen;
65 u32 ret = GSS_S_DEFECTIVE_TOKEN; 66 u32 ret = GSS_S_DEFECTIVE_TOKEN;
66 67
67 dprintk("RPC: spkm3_read_token read_token->len %d\n", read_token->len);
68
69 if (g_verify_token_header((struct xdr_netobj *) &ctx->mech_used, 68 if (g_verify_token_header((struct xdr_netobj *) &ctx->mech_used,
70 &bodysize, &ptr, read_token->len)) 69 &bodysize, &ptr, read_token->len))
71 goto out; 70 goto out;
72 71
73 /* decode the token */ 72 /* decode the token */
74 73
75 if (toktype == SPKM_MIC_TOK) { 74 if (toktype != SPKM_MIC_TOK) {
76 75 dprintk("RPC: BAD SPKM3 token type: %d\n", toktype);
77 if ((ret = spkm3_verify_mic_token(&ptr, &mic_hdrlen, &cksum))) 76 goto out;
78 goto out; 77 }
79 78
80 if (*cksum++ != 0x03) { 79 if ((ret = spkm3_verify_mic_token(&ptr, &mic_hdrlen, &cksum)))
81 dprintk("RPC: spkm3_read_token BAD checksum type\n"); 80 goto out;
82 goto out; 81
83 } 82 if (*cksum++ != 0x03) {
84 md5elen = *cksum++; 83 dprintk("RPC: spkm3_read_token BAD checksum type\n");
85 cksum++; /* move past the zbit */ 84 goto out;
86 85 }
87 if(!decode_asn1_bitstring(&wire_cksum, cksum, md5elen - 1, 16)) 86 md5elen = *cksum++;
88 goto out; 87 cksum++; /* move past the zbit */
89 88
90 /* HARD CODED FOR MD5 */ 89 if (!decode_asn1_bitstring(&wire_cksum, cksum, md5elen - 1, 16))
91 90 goto out;
92 /* compute the checksum of the message. 91
93 * ptr + 2 = start of header piece of checksum 92 /* HARD CODED FOR MD5 */
94 * mic_hdrlen + 2 = length of header piece of checksum 93
95 */ 94 /* compute the checksum of the message.
96 ret = GSS_S_DEFECTIVE_TOKEN; 95 * ptr + 2 = start of header piece of checksum
97 code = make_checksum(CKSUMTYPE_RSA_MD5, ptr + 2, 96 * mic_hdrlen + 2 = length of header piece of checksum
98 mic_hdrlen + 2, 97 */
99 message_buffer, 0, &md5cksum); 98 ret = GSS_S_DEFECTIVE_TOKEN;
100 99 if (!g_OID_equal(&ctx->intg_alg, &hmac_md5_oid)) {
101 if (code) 100 dprintk("RPC: gss_spkm3_seal: unsupported I-ALG algorithm\n");
102 goto out; 101 goto out;
103 102 }
104 dprintk("RPC: spkm3_read_token: digest wire_cksum.len %d:\n", 103
105 wire_cksum.len); 104 checksum_type = CKSUMTYPE_HMAC_MD5;
106 105
107 ret = GSS_S_BAD_SIG; 106 code = make_spkm3_checksum(checksum_type,
108 code = memcmp(md5cksum.data, wire_cksum.data, wire_cksum.len); 107 &ctx->derived_integ_key, ptr + 2, mic_hdrlen + 2,
109 if (code) 108 message_buffer, 0, &md5cksum);
110 goto out; 109
111 110 if (code)
112 } else { 111 goto out;
113 dprintk("RPC: BAD or UNSUPPORTED SPKM3 token type: %d\n",toktype); 112
113 ret = GSS_S_BAD_SIG;
114 code = memcmp(md5cksum.data, wire_cksum.data, wire_cksum.len);
115 if (code) {
116 dprintk("RPC: bad MIC checksum\n");
114 goto out; 117 goto out;
115 } 118 }
116 119
120
117 /* XXX: need to add expiration and sequencing */ 121 /* XXX: need to add expiration and sequencing */
118 ret = GSS_S_COMPLETE; 122 ret = GSS_S_COMPLETE;
119out: 123out: