/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <strings.h>
#include <libgen.h>
#include <pthread.h>
#include <ctype.h>
#include <security/cryptoki.h>
#include <cryptoutil.h>
/* PKCS#11 URI prefix and attributes. */
/*
* Gets a hexadecimal string of the xx:xx:xx-like format and fills the output
* buffer with bytes representing each of the hexadecimal numbers. Returns 0 on
* error (missing ':', not a hexadecimal character (eg. 'z'), output buffer
* overflow, etc.), or the number of hexadecimal numbers processed.
*
* Returns:
* 0
* on failure
* >0
* number of bytes returned via the output parameter
*/
static int
{
int i, len, n;
/* Counter of the processed bytes. */
i = 0;
/* Counter for the used output bytes. */
n = 0;
while (i < len) {
/* We require at least one hexadecimal character. */
return (0);
++i;
/* And we accept the 2nd one if it is there. */
++i;
}
/* Output buffer overflow? */
if ((n + 1) > out_len)
return (0);
/* Still some bytes to process? */
if (i < len) {
/* ':' is the only acceptable delimiter. */
if (str[i] != ':')
return (0);
/* Skip ':' */
++i;
}
++n;
}
return (n);
}
static char hex_table[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11,
12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
/*
* Performs inline percent-decoding of string str.
* String must be zero-terminated! Implies, that str must not be NULL either.
* Returns: length of the resulting string
*/
{
char *p, *q;
p = q = str;
while (*p != '\0') {
/* cannot overflow - zero-termination constraint on str */
p += 3;
} else {
/* not copying common unescaped prefix */
if (q != p) {
*q = *p;
}
p++;
}
q++;
}
*q = '\0';
return (q - str);
}
/*
* Process the PKCS#11 URI. The function expects an allocated URI structure. The
* caller is later expected to call pkcs11_free_uri() when the parsed URI is no
* longer needed.
*
* Note that the caller needs to call pkcs11_free_uri() on the 'uri' structure
* only if PK11_URI_OK is returned but it is always safe to do that since
* pkcs11_free_uri() checks for NULLs and the structure is zeroized here before
* it is used.
*
* Returns:
* PK11_URI_OK
* success
* PK11_URI_INVALID
* invalid PKCS#11 URI (one that has the "pkcs11:" prefix but is
* otherwise incorrectly specified)
* PK11_MALLOC_ERROR
* malloc(3C) failed when allocating one of the internal buffers.
* This error can be returned only after the correct "pkcs11:"
* prefix was found but it does not give any information about the
* syntax correctness of the URI body.
* PK11_URI_VALUE_OVERFLOW
* some attributes in the URI are of the fixed length according to
* the spec. If any of those attributes overflows we report an
* error
* PK11_NOT_PKCS11_URI
* the URI supplied is not the PKCS#11 URI at all (does not have
* the "pkcs11:" prefix)
*/
int
{
/* Initialize the structure. */
/* Be really safe. */
/* Check that we have the correct PKCS#11 URI prefix. */
return (PK11_NOT_PKCS11_URI);
/* Dup the string and skip over the prefix then. */
return (PK11_MALLOC_ERROR);
/*
* Using strtok_r() would silently skip over multiple semicolons. We
* must check such situation before moving on. We must also avoid ';' as
* the first and the last character of the URI.
*/
goto bad_uri;
/* Now parse the URI. */
/* "tok" is not empty so there will be something in "name". */
/* Check whether there is '=' at all. */
goto bad_uri;
/*
* Fill out the URI structure. We do not accept duplicate
* attributes.
*/
/* Check for duplicity. */
goto bad_uri;
if (len > 32)
goto value_overflow;
goto malloc_failed;
/* Check for duplicity. */
goto bad_uri;
if (len > 32)
goto value_overflow;
goto malloc_failed;
/* Check for duplicity. */
goto bad_uri;
if (len > 16)
goto value_overflow;
goto malloc_failed;
/* Check for duplicity. */
goto bad_uri;
if (len > 16)
goto value_overflow;
goto malloc_failed;
/* Check for duplicity. */
goto bad_uri;
/*
* We can have maximum of PK11_MAX_ID_LEN 2-byte
* numbers separated by ':'s, like
* 01:02:0A:FF:...
*/
PK11_MAX_ID_LEN - 1) {
goto value_overflow;
}
goto malloc_failed;
goto bad_uri;
/* Check for duplicity. */
goto bad_uri;
if (len > PK11_MAX_OBJECT_LEN)
goto value_overflow;
goto malloc_failed;
/*
* Check for duplicity. objecttype can not be empty, it
* would not make sense.
*/
goto bad_uri;
else
goto bad_uri;
/* Check for duplicity. */
if (len > MAXPATHLEN)
goto value_overflow;
goto malloc_failed;
/* Empty pinfile makes no sense. */
goto bad_uri;
} else
goto bad_uri;
else
/* Unknown attribute name. */
goto bad_uri;
}
return (PK11_URI_OK);
return (PK11_MALLOC_ERROR);
return (PK11_URI_INVALID);
return (PK11_URI_VALUE_OVERFLOW);
}
/*
* Free the PKCS#11 URI structure attributes but do not free the structure
* itself. The caller needs to call this function only if pkcs11_parse_uri()
* returned PK11_URI_OK. However, it is always safe to do that for other return
* codes as well since the structure is zeroized at the beginning of
* pkcs11_parse_uri() and we check for NULLs here.
*/
void
{
}