Doc fix.
[gsasl.git] / lib / gs2 / gs2parser.c
blob308686c0d7818d45d0156ea099b35916a6ded380
1 /* gs2parser.h --- GS2 parser.
2 * Copyright (C) 2006 Simon Josefsson
4 * This file is part of GNU SASL Library.
6 * GNU SASL Library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
11 * GNU SASL Library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with GNU SASL Library; if not, write to the Free
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
23 #include "gs2parser.h"
25 #include <stdint.h>
27 /* Parse a GS2 token in TOKEN of TOKLEN length, check the length
28 field, and set the appropriate values in OUT, if OUT is non-NULL.
29 The values in OUT that are set points into the TOKEN buffer, so
30 they must not be deallocated. On success, the function sets all
31 values in OUT. Returns 0 on success, or negative on failures
32 (i.e., the input is invalid). */
33 int
34 gs2_parser (const char *token, size_t toklen, struct gs2_token *out)
36 uint32_t ctxlen;
38 /* Packets shorter than 4 octets are invalid. */
39 if (toklen < 4)
40 return -1;
42 ctxlen = token[0] << 24 | token[1] << 16 | token[2] << 8 | token[3];
44 /* If the length field is longer than the entire packet size, minus
45 4 octets, the packet is invalid. */
46 if (ctxlen > toklen - 4)
47 return -2;
49 if (!out)
50 return -3;
52 out->context_length = ctxlen;
53 out->context_token = ctxlen > 0 ? token + 4 : NULL;
55 out->wrap_length = toklen - 4 - ctxlen;
56 out->wrap_token = out->wrap_length > 0 ? token + 4 + ctxlen : NULL;
58 return 0;
61 /* Encode a GS2 token into OUT, a pre-allocated buffer of size at
62 least CONTEXT_LENGTH + WRAP_LENGTH + 4. CONTEXT is the context
63 token, of length CONTEXT_LENGTH. WRAP is the wrap token, of length
64 WRAP_LENGTH. If OUTLEN is non-NULL, the length of the output token
65 is written to it on successful exit. If OUT is NULL, no data is
66 written, but the input lengths are verified, and the OUTLEN
67 variable is written (if applicable). This can be used to determine
68 how large buffer must be allocated for OUT. Returns 0 on success,
69 or negative on failures (i.e., the input is invalid). */
70 int
71 gs2_encode (const char *context, size_t context_length,
72 const char *wrap, size_t wrap_length,
73 char *out, size_t *outlen)
75 size_t totlen = 4 + context_length + wrap_length;
76 uint32_t ctxlen;
78 /* Reject out of bounds conditions. */
79 if (totlen > UINT32_MAX || totlen < context_length || totlen < wrap_length)
80 return -1;
82 /* Only time we accept NULL inputs is for zero-length inputs. */
83 if (context == NULL && context_length != 0)
84 return -2;
85 if (wrap == NULL && wrap_length != 0)
86 return -3;
88 if (outlen)
89 *outlen = totlen;
91 if (!out)
92 return 0;
94 out[0] = (context_length >> 24) & 0xFF;
95 out[1] = (context_length >> 16) & 0xFF;
96 out[2] = (context_length >> 8) & 0xFF;
97 out[3] = context_length & 0xFF;
99 if (context)
100 memcpy (out + 4, context, context_length);
101 if (wrap)
102 memcpy (out + 4 + context_length, wrap, wrap_length);
104 return 0;