gs2parser.c

Go to the documentation of this file.
00001 /* gs2parser.h --- GS2 parser.
00002  * Copyright (C) 2006, 2007  Simon Josefsson
00003  *
00004  * This file is part of GNU SASL Library.
00005  *
00006  * GNU SASL Library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public License
00008  * as published by the Free Software Foundation; either version 2.1 of
00009  * the License, or (at your option) any later version.
00010  *
00011  * GNU SASL Library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with GNU SASL Library; if not, write to the Free
00018  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "gs2parser.h"
00024 
00025 #include <stdint.h>
00026 
00027 /* Parse a GS2 token in TOKEN of TOKLEN length, check the length
00028    field, and set the appropriate values in OUT, if OUT is non-NULL.
00029    The values in OUT that are set points into the TOKEN buffer, so
00030    they must not be deallocated.  On success, the function sets all
00031    values in OUT.  Returns 0 on success, or negative on failures
00032    (i.e., the input is invalid).  */
00033 int
00034 gs2_parser (const char *token, size_t toklen, struct gs2_token *out)
00035 {
00036   uint32_t context_length, wrap_length;
00037 
00038   if (!out)
00039     return -1;
00040 
00041   /* Messages shorter than or equal to 8 octets are invalid. */
00042   if (toklen <= 8)
00043     return -1;
00044 
00045   context_length =
00046     (token[0] << 24) & 0xFF000000 |
00047     (token[1] << 16) & 0xFF0000 |
00048     (token[2] << 8) & 0xFF00 | (token[3]) & 0xFF;
00049 
00050   wrap_length =
00051     (token[4] << 24) & 0xFF000000 |
00052     (token[5] << 16) & 0xFF0000 |
00053     (token[6] << 8) & 0xFF00 | (token[7]) & 0xFF;
00054 
00055   /* Check that lengths are not out of bounds. */
00056   if (context_length > toklen || wrap_length > toklen ||
00057       context_length + wrap_length + 8 != toklen)
00058     return -1;
00059 
00060   out->context_length = context_length;
00061   if (context_length > 0)
00062     out->context_token = token + 8;
00063   else
00064     out->context_token = NULL;
00065 
00066   out->wrap_length = wrap_length;
00067   if (wrap_length > 0)
00068     out->wrap_token = token + 8 + context_length;
00069   else
00070     out->wrap_token = NULL;
00071 
00072   return 0;
00073 }
00074 
00075 /* Encode a GS2 token into newly allocated OUT buffer.  CONTEXT is the
00076    context token, of length CONTEXT_LENGTH.  WRAP is the wrap token,
00077    of length WRAP_LENGTH.  If OUTLEN is non-NULL, the length of the
00078    output token is written to it on successful exit.  If OUT is NULL,
00079    no data is written, but the input lengths are verified, and the
00080    OUTLEN variable is written (if applicable).  This can be used to
00081    determine how large the output will be.  Returns 0 on success, or
00082    negative on failures (i.e., the input is invalid). */
00083 int
00084 gs2_encode (const char *context, size_t context_length,
00085             const char *wrap, size_t wrap_length, char **out, size_t * outlen)
00086 {
00087   size_t totlen = 4 + context_length + wrap_length;
00088   uint32_t ctxlen;
00089 
00090   /* Reject out of bounds conditions. */
00091   if (totlen > UINT32_MAX || totlen < context_length || totlen < wrap_length)
00092     return -1;
00093 
00094   /* Only time we accept NULL inputs is for zero-length inputs. */
00095   if (context == NULL && context_length != 0)
00096     return -2;
00097   if (wrap == NULL && wrap_length != 0)
00098     return -3;
00099 
00100   if (outlen)
00101     *outlen = totlen;
00102 
00103   if (!out)
00104     return 0;
00105 
00106   *out = malloc (*outlen);
00107   if (!*out)
00108     return -4;
00109 
00110   (*out)[0] = (context_length >> 24) & 0xFF;
00111   (*out)[1] = (context_length >> 16) & 0xFF;
00112   (*out)[2] = (context_length >> 8) & 0xFF;
00113   (*out)[3] = context_length & 0xFF;
00114 
00115   if (context)
00116     memcpy (*out + 4, context, context_length);
00117   if (wrap)
00118     memcpy (*out + 4 + context_length, wrap, wrap_length);
00119 
00120   return 0;
00121 }

Generated on Tue Oct 21 18:28:19 2008 for gsasl by  doxygen 1.5.6