rdn_parser.c revision 9a7670889e9c36ec355371e6b02f2d9084f040dc
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* File: rdn_parser.c
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <strings.h>
#include <stdlib.h>
#include <kmfapi.h>
#include <kmfapiP.h>
#include <ber_der.h>
#include <rdn_parser.h>
#include <stdio.h>
#include <values.h>
/*
* The order here is important. The OIDs are arranged in order of
* significance. The CN is the most specific value, the C (country)
* is less specific, etc. Add to this list with care.
*/
static const struct NameToKind name2kinds[] = {
{ "OU", OID_AVA_ORGANIZATIONAL_UNIT_NAME,
{ "ST", OID_AVA_STATE_OR_PROVINCE,
{ 0, OID_UNKNOWN, NULL}
};
static KMF_BOOL
{
if (!IS_PRINTABLE(ch)) {
return (B_FALSE);
}
}
return (B_TRUE);
}
static KMF_BOOL
{
if ((ch & 0x80)) {
return (B_FALSE);
}
}
return (B_TRUE);
}
static void
{
bp++;
}
}
static KMF_RETURN
{
int taglen;
if (tagBufSize <= 0)
return (KMF_ERR_INTERNAL);
/* skip optional leading space */
/* nothing left */
return (KMF_ERR_RDN_PARSER);
}
/* fill tagBuf */
taglen = 0;
if (++taglen >= tagBufSize) {
return (KMF_ERR_RDN_PARSER);
}
}
/* null-terminate tagBuf -- guaranteed at least one space left */
*tagBufp++ = 0;
/*
* skip trailing spaces till we hit something - should be
* an equal sign
*/
/* nothing left */
return (KMF_ERR_RDN_PARSER);
}
/* should be an equal sign */
return (KMF_ERR_RDN_PARSER);
}
/* skip over the equal sign */
(*pbp)++;
return (KMF_OK);
}
static KMF_RETURN
{
int vallen;
if (valBufSize <= 0)
return (KMF_ERR_INTERNAL);
/* skip optional leading space */
/* nothing left */
return (KMF_ERR_RDN_PARSER);
}
/* quoted? */
if (*bp == C_DOUBLE_QUOTE) {
/* skip over it */
bp++;
} else {
}
vallen = 0;
char c = *bp;
if (c == C_BACKSLASH) {
/* escape character */
bp++;
/*
* escape charater must appear with paired char
*/
return (KMF_ERR_RDN_PARSER);
}
} else if (!isQuoted && SPECIAL_CHAR(c)) {
/* unescaped special and not within quoted value */
break;
} else if (c == C_DOUBLE_QUOTE) {
/* reached unescaped double quote */
break;
}
/* append character */
vallen++;
if (vallen >= valBufSize) {
return (KMF_ERR_RDN_PARSER);
}
}
/* stip trailing spaces from unquoted values */
if (!isQuoted) {
valBufp--;
valBufp--;
}
valBufp++;
}
}
if (isQuoted) {
/* insist that we stopped on a double quote */
if (*bp != C_DOUBLE_QUOTE) {
return (KMF_ERR_RDN_PARSER);
}
/* skip over the quote and skip optional space */
bp++;
}
/* empty value -- not allowed */
return (KMF_ERR_RDN_PARSER);
}
/* null-terminate valBuf -- guaranteed at least one space left */
*valBufp++ = 0;
return (KMF_OK);
}
static KMF_RETURN
{
/* Each RDN has 1 AttrTypeAndValue */
return (KMF_OK);
}
static KMF_RETURN
{
return (KMF_ERR_BAD_PARAMETER);
return (KMF_ERR_MEMORY);
return (ret);
}
static KMF_RETURN
{
sizeof (KMF_X509_TYPE_VALUE_PAIR));
return (KMF_ERR_MEMORY);
} else {
return (KMF_ERR_MEMORY);
}
/* Illegal AVA type */
return (rv);
}
}
return (rv);
}
static KMF_RETURN
{
const struct NameToKind *n2k;
int vt;
int valLen;
char *bp;
char tagBuf[32];
char valBuf[384];
return (rv);
return (rv);
/* insist that if we haven't finished we've stopped on a separator */
return (KMF_ERR_RDN_ATTR);
}
/* ok, skip over separator */
bp++;
}
if (valLen != 2) {
return (KMF_ERR_RDN_ATTR);
}
return (KMF_ERR_RDN_ATTR);
}
vt = BER_IA5STRING;
} else {
/*
* Hack -- for rationale see X.520
* DirectoryString defn
*/
if (IsPrintable((unsigned char *)valBuf,
valLen)) {
valLen)) {
vt = BER_T61STRING;
}
}
return (rv);
}
}
/* matched no kind -- invalid tag */
return (KMF_ERR_RDN_ATTR);
}
static int
rdnavcompare(const void *a, const void *b)
{
const struct NameToKind *n2k;
r1 = (KMF_X509_RDN *)a;
r2 = (KMF_X509_RDN *)b;
/*
* The "Name2Kinds" list is ordered by significance.
* Compare the "ranking" of each of the OIDs to determine
* the result.
*/
for (n2k = name2kinds, i = 0;
n2k++, i++) {
p1 = i;
p2 = i;
}
}
return (-1);
return (1);
else /* If equal, treat as if it is less than */
return (1);
}
{
char *bp, *e;
while (bp < e) {
}
/*
* Canonicalize the DN by sorting the elements
* in little-endian order, as per RFC 1485:
* order (most significant component last)."
*/
sizeof (KMF_X509_RDN),
/* return result */
return (rv);
return (rv);
}
static KMF_BOOL
{
}
/*
* Generic routine to compare 2 RDN structures.
*
* Because the ordering of the AV pairs may not be
* the same, we must compare each AV pair individually
*
* Return 0 if equal, 1 if not.
*/
int
{
int i, j;
return (1);
return (1);
for (i = 0; i < name1->numberOfRDNs; i++) {
r2 = (KMF_X509_RDN *)
av2 = (KMF_X509_TYPE_VALUE_PAIR *)
}
/*
* If the current AV from name1 was not found in name2,
* we are done.
*/
if (!avfound)
return (1);
}
/* If we got this far, it must be a match */
return (0);
}