Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F35336872
oid.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
7 KB
Subscribers
None
oid.c
View Options
/* oid.c - Object identifier helper functions
* Copyright (C) 2001, 2009, 2012 g10 Code GmbH
*
* This file is part of KSBA.
*
* KSBA is free software; you can redistribute it and/or modify
* it under the terms of either
*
* - 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.
*
* KSBA 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 copies of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, see <http://www.gnu.org/licenses/>.
*/
#include
<config.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<assert.h>
#include
"util.h"
#include
"asn1-func.h"
#include
"convert.h"
/**
* ksba_oid_to_str:
* @buffer: A BER encoded OID
* @length: The length of this OID
*
* Take a buffer with an object identifier in BER encoding and return
* a string representing this OID. We do not use the ASN.1 syntax
* here but delimit the arcs with dots, so it is easier to parse in
* most cases. This dotted-decimal notation is also known as LDAPOID
* string and described in RFC-2251.
*
* The function returns an empty string for an empty buffer and does
* no interpretation of the OID. The caller must free the returned
* string using ksba_free() or the function he has registered as a
* replacement.
*
*
* Return value: A allocated string or NULL in case of memory problem.
**/
char
*
ksba_oid_to_str
(
const
char
*
buffer
,
size_t
length
)
{
const
unsigned
char
*
buf
=
buffer
;
char
*
string
,
*
p
;
int
n
=
0
;
unsigned
long
val
,
valmask
;
valmask
=
(
unsigned
long
)
0xfe
<<
(
8
*
(
sizeof
(
valmask
)
-
1
));
/* To calculate the length of the string we can safely assume an
upper limit of 3 decimal characters per byte. Two extra bytes
account for the special first octect */
string
=
p
=
xtrymalloc
(
length
*
(
1
+
3
)
+
2
+
1
);
if
(
!
string
)
return
NULL
;
if
(
!
length
)
{
*
p
=
0
;
return
string
;
}
if
(
buf
[
0
]
<
40
)
p
+=
sprintf
(
p
,
"0.%d"
,
buf
[
n
]);
else
if
(
buf
[
0
]
<
80
)
p
+=
sprintf
(
p
,
"1.%d"
,
buf
[
n
]
-40
);
else
{
val
=
buf
[
n
]
&
0x7f
;
while
(
(
buf
[
n
]
&
0x80
)
&&
++
n
<
length
)
{
if
(
(
val
&
valmask
)
)
goto
badoid
;
/* Overflow. */
val
<<=
7
;
val
|=
buf
[
n
]
&
0x7f
;
}
if
(
val
<
80
)
goto
badoid
;
val
-=
80
;
sprintf
(
p
,
"2.%lu"
,
val
);
p
+=
strlen
(
p
);
}
for
(
n
++
;
n
<
length
;
n
++
)
{
val
=
buf
[
n
]
&
0x7f
;
while
(
(
buf
[
n
]
&
0x80
)
&&
++
n
<
length
)
{
if
(
(
val
&
valmask
)
)
goto
badoid
;
/* Overflow. */
val
<<=
7
;
val
|=
buf
[
n
]
&
0x7f
;
}
sprintf
(
p
,
".%lu"
,
val
);
p
+=
strlen
(
p
);
}
*
p
=
0
;
return
string
;
badoid
:
/* Return a special OID (gnu.gnupg.badoid) to indicate the error
case. The OID is broken and thus we return one which can't do
any harm. Formally this does not need to be a bad OID but an OID
with an arc that can't be represented in a 32 bit word is more
than likely corrupt. */
xfree
(
string
);
return
xtrystrdup
(
"1.3.6.1.4.1.11591.2.12242973"
);
}
/* Take the OID at NODE and return it in string format */
char
*
_ksba_oid_node_to_str
(
const
unsigned
char
*
image
,
AsnNode
node
)
{
if
(
!
node
||
node
->
type
!=
TYPE_OBJECT_ID
||
node
->
off
==
-1
)
return
NULL
;
return
ksba_oid_to_str
(
image
+
node
->
off
+
node
->
nhdr
,
node
->
len
);
}
static
size_t
make_flagged_int
(
unsigned
long
value
,
char
*
buf
,
size_t
buflen
)
{
int
more
=
0
;
int
shift
;
/* fixme: figure out the number of bits in an ulong and start with
that value as shift (after making it a multiple of 7) a more
straigtforward implementation is to do it in reverse order using
a temporary buffer - saves a lot of compares */
for
(
more
=
0
,
shift
=
28
;
shift
>
0
;
shift
-=
7
)
{
if
(
more
||
value
>=
(
1
<<
shift
))
{
buf
[
buflen
++
]
=
0x80
|
(
value
>>
shift
);
value
-=
(
value
>>
shift
)
<<
shift
;
more
=
1
;
}
}
buf
[
buflen
++
]
=
value
;
return
buflen
;
}
/**
* ksba_oid_from_str:
* @string: A string with the OID in dotted decimal form
* @rbuf: Returns the DER encoded OID
* @rlength: and its length
*
* Convertes the OID given in dotted decimal form to an DER encoding
* and returns it in allocated buffer rbuf and its length in rlength.
* rbuf is set to NULL in case an error is returned.
* Scanning stops at the first white space.
*
* The caller must free the returned buffer using ksba_free() or the
* function he has registered as a replacement.
*
* Return value: 0 on success or an error value
**/
gpg_error_t
ksba_oid_from_str
(
const
char
*
string
,
unsigned
char
**
rbuf
,
size_t
*
rlength
)
{
unsigned
char
*
buf
;
size_t
buflen
;
unsigned
long
val1
,
val
;
const
char
*
endp
;
int
arcno
;
if
(
!
string
||
!
rbuf
||
!
rlength
)
return
gpg_error
(
GPG_ERR_INV_VALUE
);
*
rbuf
=
NULL
;
*
rlength
=
0
;
/* we allow the OID to be prefixed with either "oid." or "OID." */
if
(
!
strncmp
(
string
,
"oid."
,
4
)
||
!
strncmp
(
string
,
"OID."
,
4
))
string
+=
4
;
if
(
!*
string
)
return
gpg_error
(
GPG_ERR_INV_VALUE
);
/* we can safely assume that the encoded OID is shorter than the string */
buf
=
xtrymalloc
(
strlen
(
string
)
+
2
);
if
(
!
buf
)
return
gpg_error
(
GPG_ERR_ENOMEM
);
buflen
=
0
;
val1
=
0
;
/* avoid compiler warnings */
arcno
=
0
;
do
{
arcno
++
;
val
=
strtoul
(
string
,
(
char
**
)
&
endp
,
10
);
if
(
!
digitp
(
string
)
||
!
(
*
endp
==
'.'
||
!*
endp
))
{
xfree
(
buf
);
return
gpg_error
(
GPG_ERR_INV_OID_STRING
);
}
if
(
*
endp
==
'.'
)
string
=
endp
+
1
;
if
(
arcno
==
1
)
{
if
(
val
>
2
)
break
;
/* not allowed, error catched below */
val1
=
val
;
}
else
if
(
arcno
==
2
)
{
/* need to combine the first to arcs in one octet */
if
(
val1
<
2
)
{
if
(
val
>
39
)
{
xfree
(
buf
);
return
gpg_error
(
GPG_ERR_INV_OID_STRING
);
}
buf
[
buflen
++
]
=
val1
*
40
+
val
;
}
else
{
val
+=
80
;
buflen
=
make_flagged_int
(
val
,
buf
,
buflen
);
}
}
else
{
buflen
=
make_flagged_int
(
val
,
buf
,
buflen
);
}
}
while
(
*
endp
==
'.'
);
if
(
arcno
==
1
)
{
/* it is not possible to encode only the first arc */
xfree
(
buf
);
return
gpg_error
(
GPG_ERR_INV_OID_STRING
);
}
*
rbuf
=
buf
;
*
rlength
=
buflen
;
return
0
;
}
/* Convert the string in BUFFER which is of length BUFLEN to its DER
encoding and returns it in a new allocated buffer RBUF and its
length in RLENGTH. RBUF is set to NULL if an error is returned.
The caller must free the returned buffer using ksba_free() or the
function he has registered as a replacement. */
gpg_error_t
_ksba_oid_from_buf
(
const
void
*
buffer
,
size_t
buflen
,
unsigned
char
**
rbuf
,
size_t
*
rlength
)
{
gpg_error_t
err
;
char
*
string
;
string
=
xtrymalloc
(
buflen
+
1
);
if
(
!
string
)
{
*
rbuf
=
NULL
;
*
rlength
=
0
;
return
gpg_error_from_syserror
();
}
memcpy
(
string
,
buffer
,
buflen
);
string
[
buflen
]
=
0
;
err
=
ksba_oid_from_str
(
string
,
rbuf
,
rlength
);
xfree
(
string
);
return
err
;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Fri, Feb 6, 8:10 AM (3 h, 58 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
e1/8e/73787241da5485afa2abe130c9dc
Attached To
rK libksba
Event Timeline
Log In to Comment