all: fix spelling and typos
[gnupg.git] / common / userids.c
index 88593bf..01f2cd8 100644 (file)
@@ -1,27 +1,34 @@
 /* userids.c - Utility functions for user ids.
  * Copyright (C) 2001, 2003, 2004, 2006,
  *               2009 Free Software Foundation, Inc.
+ * Copyright (C) 2015  g10 Code GmbH
  *
  * This file is part of GnuPG.
  *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - the GNU General Public License as published by the Free
+ *     Software Foundation; either version 2 of the License, or (at
+ *     your option) any later version.
+ *
+ * or both in parallel, as here.
+ *
+ * This file is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
-/* This file implements a few utility functions useful when working
-   with canonical encrypted S-expresions (i.e. not the S-exprssion
-   objects from libgcrypt).  */
-
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -32,7 +39,7 @@
 
 
 /* Parse the user-id NAME and build a search description for it.
- * Returns 0 on succdess or an error code.  DESC may be NULL to merely
+ * Returns 0 on success or an error code.  DESC may be NULL to merely
  * check the validity of a user-id.
  *
  * Some used rules:
@@ -64,6 +71,8 @@ gpg_error_t
 classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
 {
   const char *s;
+  char *s2 = NULL;
+  int rc = 0;
   int hexprefix = 0;
   int hexlength;
   int mode = 0;
@@ -77,14 +86,26 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
      function. */
   memset (desc, 0, sizeof *desc);
 
-  /* Skip leading spaces.  */
+  /* Skip leading and trailing spaces.  */
   for(s = name; *s && spacep (s); s++ )
     ;
+  if (*s && spacep (s + strlen(s) - 1))
+    {
+      s2 = xtrystrdup (s);
+      if (!s2)
+        {
+          rc = gpg_error_from_syserror ();
+          goto out;
+        }
+      trim_trailing_spaces (s2);
+      s = s2;
+    }
 
   switch (*s)
     {
     case 0:  /* Empty string is an error.  */
-      return gpg_error (GPG_ERR_INV_USER_ID);
+      rc = gpg_error (GPG_ERR_INV_USER_ID);
+      goto out;
 
     case '.': /* An email address, compare from end.  Note that this
                  has not yet been implemented in the search code.  */
@@ -132,7 +153,10 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
     case '/': /* Subject's DN.  */
       s++;
       if (!*s || spacep (s)) /* No DN or prefixed with a space.  */
-        return gpg_error (GPG_ERR_INV_USER_ID);
+        {
+          rc = gpg_error (GPG_ERR_INV_USER_ID);
+          goto out;
+        }
       desc->u.name = s;
       mode = KEYDB_SEARCH_MODE_SUBJECT;
       break;
@@ -146,7 +170,10 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
           { /* "#/" indicates an issuer's DN.  */
             s++;
             if (!*s || spacep (s)) /* No DN or prefixed with a space.  */
-              return gpg_error (GPG_ERR_INV_USER_ID);
+              {
+                rc = gpg_error (GPG_ERR_INV_USER_ID);
+                goto out;
+              }
             desc->u.name = s;
             mode = KEYDB_SEARCH_MODE_ISSUER;
           }
@@ -156,7 +183,10 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
               {
                  /* Check for an invalid digit in the serial number. */
                 if (!strchr("01234567890abcdefABCDEF", *si))
-                  return gpg_error (GPG_ERR_INV_USER_ID);
+                  {
+                    rc = gpg_error (GPG_ERR_INV_USER_ID);
+                    goto out;
+                  }
               }
             desc->sn = (const unsigned char*)s;
             desc->snlen = -1;
@@ -166,7 +196,10 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
               {
                 s = si+1;
                 if (!*s || spacep (s))  /* No DN or prefixed with a space.  */
-                  return gpg_error (GPG_ERR_INV_USER_ID);
+                  {
+                    rc = gpg_error (GPG_ERR_INV_USER_ID);
+                    goto out;
+                  }
                 desc->u.name = s;
                 mode = KEYDB_SEARCH_MODE_ISSUER_SN;
               }
@@ -181,19 +214,27 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
 
         se = strchr (++s,':');
         if (!se)
-          return gpg_error (GPG_ERR_INV_USER_ID);
+          {
+            rc = gpg_error (GPG_ERR_INV_USER_ID);
+            goto out;
+          }
         for (i=0,si=s; si < se; si++, i++ )
           {
             if (!strchr("01234567890abcdefABCDEF", *si))
-              return gpg_error (GPG_ERR_INV_USER_ID); /* Invalid digit.  */
+              {
+                rc = gpg_error (GPG_ERR_INV_USER_ID); /* Invalid digit.  */
+                goto out;
+              }
           }
         if (i != 32 && i != 40)
-          return gpg_error (GPG_ERR_INV_USER_ID); /* Invalid length of fpr.  */
+          {
+            rc = gpg_error (GPG_ERR_INV_USER_ID); /* Invalid length of fpr.  */
+            goto out;
+          }
         for (i=0,si=s; si < se; i++, si +=2)
           desc->u.fpr[i] = hextobyte(si);
         for (; i < 20; i++)
           desc->u.fpr[i]= 0;
-        s = se + 1;
         mode = KEYDB_SEARCH_MODE_FPR;
       }
       break;
@@ -201,7 +242,10 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
     case '&': /* Keygrip*/
       {
         if (hex2bin (s+1, desc->u.grip, 20) < 0)
-          return gpg_error (GPG_ERR_INV_USER_ID); /* Invalid. */
+          {
+            rc = gpg_error (GPG_ERR_INV_USER_ID); /* Invalid. */
+            goto out;
+          }
         mode = KEYDB_SEARCH_MODE_KEYGRIP;
       }
       break;
@@ -225,7 +269,10 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
         {
           if (hexprefix) /* A "0x" prefix without a correct
                             termination is an error.  */
-            return gpg_error (GPG_ERR_INV_USER_ID);
+            {
+              rc = gpg_error (GPG_ERR_INV_USER_ID);
+              goto out;
+            }
           /* The first characters looked like a hex number, but the
              entire string is not.  */
           hexlength = 0;
@@ -234,7 +281,9 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
       if (desc->exact)
         hexlength--; /* Remove the bang.  */
 
-      if (hexlength == 8
+      if ((hexlength == 8
+           && (s[hexlength] == 0
+               || (s[hexlength] == '!' && s[hexlength + 1] == 0)))
           || (!hexprefix && hexlength == 9 && *s == '0'))
         {
           /* Short keyid.  */
@@ -243,7 +292,9 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
           desc->u.kid[1] = strtoul( s, NULL, 16 );
           mode = KEYDB_SEARCH_MODE_SHORT_KID;
         }
-      else if (hexlength == 16
+      else if ((hexlength == 16
+                && (s[hexlength] == 0
+                    || (s[hexlength] == '!' && s[hexlength + 1] == 0)))
                || (!hexprefix && hexlength == 17 && *s == '0'))
         {
           /* Long keyid.  */
@@ -255,7 +306,9 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
           desc->u.kid[1] = strtoul (s+8, NULL, 16);
           mode = KEYDB_SEARCH_MODE_LONG_KID;
         }
-      else if (hexlength == 32
+      else if ((hexlength == 32
+                && (s[hexlength] == 0
+                    || (s[hexlength] == '!' && s[hexlength + 1] == 0)))
                || (!hexprefix && hexlength == 33 && *s == '0'))
         {
           /* MD5 fingerprint.  */
@@ -267,12 +320,17 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
             {
               int c = hextobyte(s);
               if (c == -1)
-                return gpg_error (GPG_ERR_INV_USER_ID);
+                {
+                  rc = gpg_error (GPG_ERR_INV_USER_ID);
+                  goto out;
+                }
               desc->u.fpr[i] = c;
             }
           mode = KEYDB_SEARCH_MODE_FPR16;
         }
-      else if (hexlength == 40
+      else if ((hexlength == 40
+                && (s[hexlength] == 0
+                    || (s[hexlength] == '!' && s[hexlength + 1] == 0)))
                || (!hexprefix && hexlength == 41 && *s == '0'))
         {
           /* SHA1/RMD160 fingerprint.  */
@@ -283,7 +341,10 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
             {
               int c = hextobyte(s);
               if (c == -1)
-                return gpg_error (GPG_ERR_INV_USER_ID);
+                {
+                  rc = gpg_error (GPG_ERR_INV_USER_ID);
+                  goto out;
+                }
               desc->u.fpr[i] = c;
             }
           mode = KEYDB_SEARCH_MODE_FPR20;
@@ -361,10 +422,13 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
       else
        {
           /* Hex number with a prefix but with a wrong length.  */
-          return gpg_error (GPG_ERR_INV_USER_ID);
+          rc = gpg_error (GPG_ERR_INV_USER_ID);
+          goto out;
         }
     }
 
   desc->mode = mode;
-  return 0;
+ out:
+  xfree (s2);
+  return rc;
 }