gsasl  1.8.0
digest-md5/validate.c
Go to the documentation of this file.
00001 /* validate.c --- Validate consistency of DIGEST-MD5 tokens.
00002  * Copyright (C) 2004-2012 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 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026 
00027 /* Get prototypes. */
00028 #include "validate.h"
00029 
00030 /* Get strcmp, strlen. */
00031 #include <string.h>
00032 
00033 int
00034 digest_md5_validate_challenge (digest_md5_challenge * c)
00035 {
00036   /* This directive is required and MUST appear exactly once; if
00037      not present, or if multiple instances are present, the
00038      client should abort the authentication exchange. */
00039   if (!c->nonce)
00040     return -1;
00041 
00042   /* This directive must be present exactly once if "auth-conf" is
00043      offered in the "qop-options" directive */
00044   if (c->ciphers && !(c->qops & DIGEST_MD5_QOP_AUTH_CONF))
00045     return -1;
00046   if (!c->ciphers && (c->qops & DIGEST_MD5_QOP_AUTH_CONF))
00047     return -1;
00048 
00049   return 0;
00050 }
00051 
00052 int
00053 digest_md5_validate_response (digest_md5_response * r)
00054 {
00055   /* This directive is required and MUST be present exactly
00056      once; otherwise, authentication fails. */
00057   if (!r->username)
00058     return -1;
00059 
00060   /* This directive is required and MUST be present exactly
00061      once; otherwise, authentication fails. */
00062   if (!r->nonce)
00063     return -1;
00064 
00065   /* This directive is required and MUST be present exactly once;
00066      otherwise, authentication fails. */
00067   if (!r->cnonce)
00068     return -1;
00069 
00070   /* This directive is required and MUST be present exactly once;
00071      otherwise, or if the value is 0, authentication fails. */
00072   if (!r->nc)
00073     return -1;
00074 
00075   /* This directive is required and MUST be present exactly
00076      once; if multiple instances are present, the client MUST
00077      abort the authentication exchange. */
00078   if (!r->digesturi)
00079     return -1;
00080 
00081   /* This directive is required and MUST be present exactly
00082      once; otherwise, authentication fails. */
00083   if (!*r->response)
00084     return -1;
00085 
00086   if (strlen (r->response) != DIGEST_MD5_RESPONSE_LENGTH)
00087     return -1;
00088 
00089   /* This directive MUST appear exactly once if "auth-conf" is
00090      negotiated; if required and not present, authentication fails.
00091      If the client recognizes no cipher and the server only advertised
00092      "auth-conf" in the qop option, the client MUST abort the
00093      authentication exchange.  */
00094   if (r->qop == DIGEST_MD5_QOP_AUTH_CONF && !r->cipher)
00095     return -1;
00096   if (r->qop != DIGEST_MD5_QOP_AUTH_CONF && r->cipher)
00097     return -1;
00098 
00099   return 0;
00100 }
00101 
00102 int
00103 digest_md5_validate_finish (digest_md5_finish * f)
00104 {
00105   if (!f->rspauth)
00106     return -1;
00107 
00108   /* A string of 32 hex digits */
00109   if (strlen (f->rspauth) != DIGEST_MD5_RESPONSE_LENGTH)
00110     return -1;
00111 
00112   return 0;
00113 }
00114 
00115 int
00116 digest_md5_validate (digest_md5_challenge * c, digest_md5_response * r)
00117 {
00118   if (!c->nonce || !r->nonce)
00119     return -1;
00120 
00121   if (strcmp (c->nonce, r->nonce) != 0)
00122     return -1;
00123 
00124   if (r->nc != 1)
00125     return -1;
00126 
00127   if (!c->utf8 && r->utf8)
00128     return -1;
00129 
00130   if (!((c->qops ? c->qops : DIGEST_MD5_QOP_AUTH) &
00131         (r->qop ? r->qop : DIGEST_MD5_QOP_AUTH)))
00132     return -1;
00133 
00134   if ((r->qop & DIGEST_MD5_QOP_AUTH_CONF) && !(c->ciphers & r->cipher))
00135     return -1;
00136 
00137   /* FIXME: Check more? */
00138 
00139   return 0;
00140 }