Commit much improved ASN.1 compiler from joda-choice-branch.
Highlighs for the compiler is support for CHOICE and in general better support for tags. This compiler support most of what is needed for PK-INIT, LDAP, X.509, PKCS-12 and many other protocols. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@15617 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
141
lib/asn1/CMS.asn1
Normal file
141
lib/asn1/CMS.asn1
Normal file
@@ -0,0 +1,141 @@
|
||||
-- From RFC 3369 --
|
||||
-- $Id$ --
|
||||
|
||||
CMS DEFINITIONS ::= BEGIN
|
||||
|
||||
IMPORTS CertificateSerialNumber, AlgorithmIdentifier, Name,
|
||||
Attribute, Certificate, Name, SubjectKeyIdentifier FROM rfc2459
|
||||
heim_any, heim_any_set FROM heim;
|
||||
|
||||
id-pkcs7 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
|
||||
us(840) rsadsi(113549) pkcs(1) pkcs7(7) }
|
||||
|
||||
id-pkcs7-data OBJECT IDENTIFIER ::= { id-pkcs7 1 }
|
||||
id-pkcs7-signedData OBJECT IDENTIFIER ::= { id-pkcs7 2 }
|
||||
id-pkcs7-envelopedData OBJECT IDENTIFIER ::= { id-pkcs7 3 }
|
||||
id-pkcs7-signedAndEnvelopedData OBJECT IDENTIFIER ::= { id-pkcs7 4 }
|
||||
id-pkcs7-digestedData OBJECT IDENTIFIER ::= { id-pkcs7 5 }
|
||||
id-pkcs7-encryptedData OBJECT IDENTIFIER ::= { id-pkcs7 6 }
|
||||
|
||||
CMSVersion ::= INTEGER { v0(0), v1(1), v2(2), v3(3), v4(4) }
|
||||
|
||||
DigestAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
|
||||
SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
|
||||
ContentType ::= OBJECT IDENTIFIER
|
||||
|
||||
ContentInfo ::= SEQUENCE {
|
||||
contentType ContentType,
|
||||
content [0] EXPLICIT heim_any OPTIONAL -- DEFINED BY contentType
|
||||
}
|
||||
|
||||
EncapsulatedContentInfo ::= SEQUENCE {
|
||||
eContentType ContentType,
|
||||
eContent [0] EXPLICIT OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
CertificateSet ::= heim_any_set -- SET OF
|
||||
CertificateSetReal ::= SET OF heim_any
|
||||
|
||||
CertificateList ::= Certificate
|
||||
|
||||
CertificateRevocationLists ::= SET OF CertificateList
|
||||
|
||||
IssuerAndSerialNumber ::= SEQUENCE {
|
||||
issuer Name,
|
||||
serialNumber CertificateSerialNumber
|
||||
}
|
||||
|
||||
-- RecipientIdentifier is same as SignerIdentifier,
|
||||
-- lets glue them togheter and save some bytes and share code for them
|
||||
|
||||
CMSIdentifier ::= CHOICE {
|
||||
issuerAndSerialNumber IssuerAndSerialNumber,
|
||||
subjectKeyIdentifier [0] SubjectKeyIdentifier
|
||||
}
|
||||
|
||||
SignerIdentifier ::= CMSIdentifier
|
||||
RecipientIdentifier ::= CMSIdentifier
|
||||
|
||||
SignedAttributes ::= SET OF Attribute -- SIZE (1..MAX)
|
||||
UnsignedAttributes ::= SET OF Attribute -- SIZE (1..MAX)
|
||||
|
||||
SignatureValue ::= OCTET STRING
|
||||
|
||||
SignerInfo ::= SEQUENCE {
|
||||
version CMSVersion,
|
||||
sid SignerIdentifier,
|
||||
digestAlgorithm DigestAlgorithmIdentifier,
|
||||
signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
|
||||
signatureAlgorithm SignatureAlgorithmIdentifier,
|
||||
signature SignatureValue,
|
||||
unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL
|
||||
}
|
||||
|
||||
SignerInfos ::= SET OF SignerInfo
|
||||
|
||||
SignedData ::= SEQUENCE {
|
||||
version CMSVersion,
|
||||
digestAlgorithms DigestAlgorithmIdentifiers,
|
||||
encapContentInfo EncapsulatedContentInfo,
|
||||
certificates [0] IMPLICIT CertificateSet OPTIONAL,
|
||||
crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
|
||||
signerInfos SignerInfos
|
||||
}
|
||||
|
||||
OriginatorInfo ::= SEQUENCE {
|
||||
certs [0] IMPLICIT CertificateSet OPTIONAL,
|
||||
crls [1] IMPLICIT CertificateRevocationLists OPTIONAL
|
||||
}
|
||||
|
||||
KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
|
||||
EncryptedKey ::= OCTET STRING
|
||||
|
||||
KeyTransRecipientInfo ::= SEQUENCE {
|
||||
version CMSVersion, -- always set to 0 or 2
|
||||
rid RecipientIdentifier,
|
||||
keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
|
||||
encryptedKey EncryptedKey
|
||||
}
|
||||
|
||||
RecipientInfo ::= KeyTransRecipientInfo
|
||||
|
||||
RecipientInfos ::= SET OF RecipientInfo
|
||||
|
||||
EncryptedContent ::= OCTET STRING
|
||||
|
||||
EncryptedContentInfo ::= SEQUENCE {
|
||||
contentType ContentType,
|
||||
contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
|
||||
encryptedContent [0] IMPLICIT OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
UnprotectedAttributes ::= SET OF Attribute -- SIZE (1..MAX)
|
||||
|
||||
CMSEncryptedData ::= SEQUENCE {
|
||||
version CMSVersion,
|
||||
encryptedContentInfo EncryptedContentInfo,
|
||||
unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL
|
||||
}
|
||||
|
||||
EnvelopedData ::= SEQUENCE {
|
||||
version CMSVersion,
|
||||
originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
|
||||
recipientInfos RecipientInfos,
|
||||
encryptedContentInfo EncryptedContentInfo,
|
||||
unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL
|
||||
}
|
||||
|
||||
-- Data ::= OCTET STRING
|
||||
|
||||
CMSRC2CBCParameter ::= SEQUENCE {
|
||||
rc2ParameterVersion INTEGER,
|
||||
iv OCTET STRING -- exactly 8 octets
|
||||
}
|
||||
|
||||
CMSCBCParameter ::= OCTET STRING
|
||||
|
||||
END
|
763
lib/asn1/ChangeLog
Normal file
763
lib/asn1/ChangeLog
Normal file
@@ -0,0 +1,763 @@
|
||||
2005-07-12 Love <lha@kth.se>
|
||||
|
||||
* gen_locl.h: rename function filename() to get_filename() to
|
||||
avoid shadowing
|
||||
|
||||
* lex.l: rename function filename() to get_filename() to avoid
|
||||
shadowing
|
||||
|
||||
* gen.c: rename function filename() to get_filename() to avoid
|
||||
shadowing
|
||||
|
||||
* check-der.c: add failure checks for large oid elements
|
||||
|
||||
* check-gen.c: add failure checks for tag (and large tags)
|
||||
|
||||
* der_get.c: Check for integer overflows in tags and oid elements.
|
||||
|
||||
2005-07-10 Assar Westerlund <assar@kth.se>
|
||||
|
||||
* gen_decode.c: Fix decoding of choices to select which branch to
|
||||
try based on the tag and return an error if that branch fails.
|
||||
|
||||
* check-gen.c: Fix short choice test cases.
|
||||
|
||||
2005-07-09 Assar Westerlund <assar@kth.se>
|
||||
|
||||
* symbol.c:
|
||||
* parse.y:
|
||||
* main.c:
|
||||
* lex.l:
|
||||
* gen_length.c:
|
||||
* gen_free.c:
|
||||
* gen_encode.c:
|
||||
* gen_decode.c:
|
||||
* gen_copy.c:
|
||||
* gen.c:
|
||||
* extra.c:
|
||||
* check-gen.c:
|
||||
* check-der.c:
|
||||
* check-common.c:
|
||||
* asn1_print.c:
|
||||
* asn1_gen.c:
|
||||
Use emalloc, ecalloc, and estrdup.
|
||||
Check return value from asprintf.
|
||||
Make sure that malloc(0) returning NULL is not treated as an
|
||||
error.
|
||||
|
||||
2005-07-10 Love <lha@kth.se>
|
||||
|
||||
* check-gen.c: test cases for CHOICE, its too liberal right now,
|
||||
it don't fail hard on failure on after it successfully decoded the
|
||||
first tag in a choice branch
|
||||
|
||||
* asn1_gen.c: calculate the basename for the output file,
|
||||
pretty-print tag number
|
||||
|
||||
* test.gen: sample for asn1_gen
|
||||
|
||||
* check-gen.c: check errors in SEQUENCE
|
||||
|
||||
* Makefile.am: build asn1_gen, TESTSeq and new, and class/type/tag
|
||||
string<->num converter.
|
||||
|
||||
* test.asn1: TESTSeq, for testing SEQUENCE
|
||||
|
||||
* asn1_gen.c: generator for asn1 data
|
||||
|
||||
* asn1_print.c: use class/type/tag string<->num converter.
|
||||
|
||||
* der.c: Add class/type/tag string<->num converter.
|
||||
|
||||
* der.h: Add class/type/tag string<->num converter.
|
||||
Prototypes/structures for new time bits.
|
||||
|
||||
2005-07-09 Love <lha@kth.se>
|
||||
|
||||
* der_get.c (der_get_unsigned) check for length overflow
|
||||
(der_get_integer) ditto
|
||||
(der_get_general_string) ditto
|
||||
|
||||
* der_get.c: check for overruns using SIZE_T_MAX
|
||||
|
||||
* check-der.c: check BIT STRING and OBJECT IDENTIFIER error cases
|
||||
|
||||
* check-common.c (generic_decode_fail): allocate 4K for the over
|
||||
sized memory test
|
||||
|
||||
* der_get.c (der_get_oid): check for integer overruns and
|
||||
unterminated oid correctly
|
||||
|
||||
* check-common.h (map_alloc, generic_decode_fail): prototypes
|
||||
|
||||
* check-common.c (map_alloc): make input buffer const
|
||||
(generic_decode_fail): verify decoding failures
|
||||
|
||||
2005-07-05 Love <lha@kth.se>
|
||||
|
||||
* gen_encode.c: split up the printf for SET OF, also use the
|
||||
generate name for the symbol in the SET OF, if not, the name might
|
||||
contain non valid variable name characters (like -)
|
||||
|
||||
2005-07-04 Love <lha@kth.se>
|
||||
|
||||
* Makefile.am: move pkcs12 defines into their own namespace
|
||||
|
||||
* pkcs12.asn1: move pkcs12 defines into their own namespace
|
||||
|
||||
* pkcs9.asn1: add PKCS9-friendlyName with workaround for SET OF
|
||||
bug
|
||||
|
||||
* heim_asn1.h: reuse heim_octet_string for heim_any types
|
||||
|
||||
* main.c: use optidx, handle the case where name is missing and
|
||||
use base of filename then
|
||||
|
||||
* asn1-common.h: include ASN1_MALLOC_ENCODE
|
||||
|
||||
* gen_decode.c: use less context so lower indentention level, add
|
||||
missing {} where needed
|
||||
|
||||
2005-07-02 Love <lha@kth.se>
|
||||
|
||||
* gen_copy.c: Use a global variable to keep track of if the 'goto
|
||||
fail' was used, and use that to only generate the label if needed.
|
||||
|
||||
* asn1_print.c: do indefinite form loop detection and stop after
|
||||
10000 recursive indefinite forms, stops crashing due to running
|
||||
out of stack
|
||||
|
||||
* asn1_print.c: catch badly formated indefinite length data
|
||||
(missing EndOfContent tag) add (negative) indent flag to speed up
|
||||
testing
|
||||
|
||||
2005-07-01 Love <lha@kth.se>
|
||||
|
||||
* canthandle.asn1: Can't handle primitives in CHOICE
|
||||
|
||||
* gen_decode.c: Check if malloc failes
|
||||
|
||||
* gen_copy.c: Make sure to free memory on failure
|
||||
|
||||
* gen_decode.c: Check if malloc failes, rename "reallen" to
|
||||
tagdatalen since that is what it is.
|
||||
|
||||
2005-05-29 Love <lha@kth.se>
|
||||
|
||||
* prefix Der_class with ASN1_C_ to avoid problems with system
|
||||
headerfiles that pollute the name space
|
||||
|
||||
2005-05-20 Love <lha@kth.se>
|
||||
|
||||
* pkcs12.asn1: add PKCS12CertBag
|
||||
|
||||
* pkcs9.asn1: add pkcs9 certtype x509 certificate
|
||||
|
||||
* Makefile.am: add pkcs12 certbag and pkcs9 certtype x509
|
||||
certificate
|
||||
|
||||
* pkcs12.asn1: split off PKCS12Attributes from SafeBag so it can
|
||||
be reused
|
||||
|
||||
* Makefile.am: add PKCS12Attributes
|
||||
|
||||
2005-05-10 Love <lha@kth.se>
|
||||
|
||||
* canthandle.asn1: fix tags in example
|
||||
|
||||
2005-05-02 Love <lha@kth.se>
|
||||
|
||||
* pkinit.asn1: Let the Windows nonce be an int32 (signed), if not
|
||||
it will fail when using Windows PK-INIT.
|
||||
|
||||
2005-05-01 Love <lha@kth.se>
|
||||
|
||||
* Makefile.am: add pkcs12-PBEParams
|
||||
|
||||
* pkcs12.asn1: add pkcs12-PBEParams
|
||||
|
||||
* parse.y: objid_element: exit when the condition fails
|
||||
|
||||
2005-04-26 Love <lha@kth.se>
|
||||
|
||||
* gen_glue.c: 1.8: switch the units variable to a
|
||||
function. gcc-4.1 needs the size of the structure if its defined
|
||||
as extern struct units foo_units[] an we don't want to include
|
||||
<parse_units.h> in the generate headerfile
|
||||
|
||||
2005-03-20 Love <lha@kth.se>
|
||||
|
||||
* Makefile.am: add the des-ede3-cbc oid that ansi x9.52 uses
|
||||
|
||||
* rfc2459.asn1: add the des-ede3-cbc oid that ansi x9.52 uses
|
||||
|
||||
* Makefile.am: add oids for x509
|
||||
|
||||
* rfc2459.asn1: add oids now when the compiler can handle them
|
||||
|
||||
2005-03-19 Love <lha@kth.se>
|
||||
|
||||
* Makefile.am: add pkcs9 files
|
||||
|
||||
* pkcs9.asn1: add small number of oids from pkcs9
|
||||
|
||||
2005-03-14 Love <lha@kth.se>
|
||||
|
||||
* Makefile.am: add a bunch of pkcs1/pkcs2/pkcs3/aes oids
|
||||
|
||||
* rfc2459.asn1: add a bunch of pkcs1/pkcs2/pkcs3/aes oids
|
||||
|
||||
2005-03-10 Love <lha@kth.se>
|
||||
|
||||
* k5.asn1: merge pa-numbers
|
||||
|
||||
2005-03-09 Love <lha@kth.se>
|
||||
|
||||
* Makefile.am: add oid's
|
||||
|
||||
* rfc2459.asn1: add encryption oids
|
||||
|
||||
* CMS.asn1: add signedAndEnvelopedData oid
|
||||
|
||||
* pkcs12.asn1: add pkcs12 oids
|
||||
|
||||
* CMS.asn1: add pkcs7 oids
|
||||
|
||||
2005-03-08 Love <lha@kth.se>
|
||||
|
||||
* gen.c (generate_header_of_codefile): break out the header
|
||||
section generation
|
||||
(generate_constant): generate a function that return the oid
|
||||
inside a heim_oid
|
||||
|
||||
* parse.y: fix the ordering of the oid's
|
||||
|
||||
* parse.y: handle OBJECT IDENTIFIER as value construct
|
||||
|
||||
2005-02-24 Love <lha@stacken.kth.se>
|
||||
|
||||
* Preserve content of CHOICE element that is unknown if ellipsis
|
||||
was used when defining the structure
|
||||
|
||||
2005-02-13 Love <lha@stacken.kth.se>
|
||||
|
||||
* parse.y: use ANS1_TAILQ macros
|
||||
|
||||
* *.[ch]: use ASN1_TAILQ macros
|
||||
|
||||
* asn1_queue.h: inline bsd sys/queue.h and rename TAILQ to
|
||||
ASN1_TAILQ to avoid problems with name polluting headerfiles
|
||||
|
||||
2005-01-19 Love <lha@stacken.kth.se>
|
||||
|
||||
* gen.c: pull in <krb5-types.h>
|
||||
|
||||
2005-01-10 Love <lha@stacken.kth.se>
|
||||
|
||||
* Add BMPString and UniversalString
|
||||
|
||||
* k5.asn1 (EtypeList): make INTEGER constrained (use krb5int32)
|
||||
|
||||
2005-01-07 Love <lha@stacken.kth.se>
|
||||
|
||||
* rfc2459.asn1: add GeneralNames
|
||||
|
||||
2004-11-21 Love <lha@stacken.kth.se>
|
||||
|
||||
* gen.c: use unsigned integer for len of SequenceOf/SetOf and
|
||||
bitstring names
|
||||
|
||||
2004-11-10 Love <lha@stacken.kth.se>
|
||||
|
||||
* Makefile.am: switch to krb5int32 and krb5uint32
|
||||
|
||||
* Unify that three integer types TInteger TUInteger and TBigInteger.
|
||||
Start to use constrained integers where appropriate.
|
||||
|
||||
2004-10-13 Love <lha@stacken.kth.se>
|
||||
|
||||
* CMS.asn1: remove no longer used commented out elements
|
||||
|
||||
* gen_glue.c: make units structures const
|
||||
|
||||
2004-10-12 Love <lha@stacken.kth.se>
|
||||
|
||||
* lex.l: handle hex number with [a-fA-F] in them
|
||||
|
||||
2004-10-07 Love <lha@stacken.kth.se>
|
||||
|
||||
* gen_free.c: free _save for CHOICE too
|
||||
|
||||
* rfc2459.asn1: use Name and not heim_any
|
||||
|
||||
* gen_decode.c: if malloc for _save failes, goto fail so we free
|
||||
the structure
|
||||
|
||||
* gen_copy.c: copy _save for CHOICE too
|
||||
|
||||
* gen.c: add _save for CHOICE too
|
||||
|
||||
* CMS.asn1: RecipientIdentifier and SignerIdentifier is the same
|
||||
name is CMSIdentifier and add glue for that so we can share code
|
||||
use Name and not heim_any
|
||||
|
||||
2004-10-03 Love <lha@stacken.kth.se>
|
||||
|
||||
* Makefile.am: drop AlgorithmIdentifierNonOpt add
|
||||
{RC2CBC,}CBCParameter here where they belong
|
||||
|
||||
* CMS.asn1: add {RC2CBC,}CBCParameter here where they belong
|
||||
|
||||
* rfc2459.asn1: drop AlgorithmIdentifierNonOpt
|
||||
|
||||
* rfc2459.asn1: stop using AlgorithmIdentifierNonOpt hint that we
|
||||
really want to use Name and some MS stuff
|
||||
|
||||
2004-09-05 Love <lha@stacken.kth.se>
|
||||
|
||||
* asn1_print.c: handle end of content, this is part BER support,
|
||||
however, OCTET STRING need some tweeking too.
|
||||
|
||||
* der.h: add UT_EndOfContent
|
||||
|
||||
* test.asn1: test asn1 spec file
|
||||
|
||||
* check-gen.c: check larget tags
|
||||
|
||||
* Makefile.am: add test asn1 spec file that we can use for testing
|
||||
constructs that doesn't exists in already existing spec (like
|
||||
large tags)
|
||||
|
||||
* der_put.c (der_put_tag): make sure there are space for the head
|
||||
tag when we are dealing with large tags (>30)
|
||||
|
||||
* check-gen.c: add test for tag length
|
||||
|
||||
* check-common.c: export the map_ functions for OVERRUN/UNDERRUN
|
||||
detection restore the SIGSEGV handler when test is done
|
||||
|
||||
* check-common.h: export the map_ functions for OVERRUN/UNDERRUN
|
||||
detection
|
||||
|
||||
* gen_decode.c: check that the tag-length is not longer the length
|
||||
use forwstr on some more places
|
||||
|
||||
* parse.y: revert part of 1.14.2.21, multiple IMPORT isn't allowed
|
||||
|
||||
* pkinit.asn1: correct usage of IMPORT
|
||||
|
||||
* CMS.asn1: correct usage of IMPORT
|
||||
|
||||
* pkcs8.asn1: pkcs8, encrypting private key
|
||||
|
||||
* pkcs12.asn1: pkcs12, key/crl/certificate file transport PDU
|
||||
|
||||
* Makefile.am: add pkcs8 and pkcs12
|
||||
|
||||
* der_free.c: reset length when freing primitives
|
||||
|
||||
* CMS.asn1: add EncryptedData
|
||||
|
||||
2004-08-26 Love <lha@stacken.kth.se>
|
||||
|
||||
* gen_decode.c (decode_type): if the entry is already optional
|
||||
when parsing a tag and we allocate the structure, not pass down
|
||||
optional since that will case the subtype's decode_type also to
|
||||
allocate an entry. and we'll leak an entry. Bug from Luke Howard
|
||||
<lukeh@padl.com>. While here, use calloc.
|
||||
|
||||
2004-04-29 Love <lha@stacken.kth.se>
|
||||
|
||||
* k5.asn1: shift the last added etypes one step so rc2 doesn't
|
||||
stomp on cram-md5
|
||||
|
||||
2004-04-26 Love <lha@stacken.kth.se>
|
||||
|
||||
* k5.asn1: add ETYPE_AESNNN_CBC_NONE
|
||||
|
||||
* CMS.asn1: add CMS symmetrical parameters moved to k5.asn1
|
||||
|
||||
* k5.asn1: add CMS symmetrical parameters here, more nametypes
|
||||
enctype rc2-cbc
|
||||
|
||||
2004-04-25 Love <lha@stacken.kth.se>
|
||||
|
||||
* gen_decode.c: free data on decode failure
|
||||
|
||||
2004-04-24 Love <lha@stacken.kth.se>
|
||||
|
||||
* Makefile.am: add CBCParameter and RC2CBCParameter
|
||||
|
||||
* CMS.asn1: add CBCParameter and RC2CBCParameter
|
||||
|
||||
2004-04-20 Love <lha@stacken.kth.se>
|
||||
|
||||
* check-der.c: add simple test for oid's, used to trigger malloc
|
||||
bugs in you have picky malloc (like valgrind/purify/third)
|
||||
|
||||
* der_get.c (der_get_oid): handle all oid components being smaller
|
||||
then 127 and allocate one extra element since first byte is split
|
||||
to to elements.
|
||||
|
||||
2004-04-16 Love <lha@stacken.kth.se>
|
||||
|
||||
* canthandle.asn1: one thing handled
|
||||
|
||||
* gen_decode.c: handle OPTIONAL CONS-tag-less elements
|
||||
|
||||
* der_length.c (length_len): since length is no longer the same as
|
||||
an unsigned, do the length counting here. ("unsigned" is zero
|
||||
padded when most significate bit is set, length is not)
|
||||
|
||||
2004-04-12 Love <lha@stacken.kth.se>
|
||||
|
||||
* canthandle.asn1: document by example what the encoder can't
|
||||
handle right now
|
||||
|
||||
* Makefile.am: add more stuff needed whem implementing x509
|
||||
preserve TBSCertificate
|
||||
|
||||
* rfc2459.asn1: add more stuff needed whem implementing x509
|
||||
|
||||
* CMS.asn1: move some type to rfc2459.asn1 where they belong (and
|
||||
import them)
|
||||
|
||||
* gen.c: preserve the raw data when asked too
|
||||
|
||||
* gen_decode.c: preserve the raw data when asked too
|
||||
|
||||
* gen_copy.c: preserve the raw data when asked too
|
||||
|
||||
* gen_free.c: preserve the raw data when asked too
|
||||
|
||||
* gen_locl.h: add preserve_type
|
||||
|
||||
* heim_asn1.h: add heim_any_cmp
|
||||
|
||||
* main.c: add flag --preserve-binary=Symbol1,Symbol2,... that make
|
||||
the compiler generate stubs to save the raw data, its not used
|
||||
right now when generating the stat
|
||||
|
||||
* k5.asn1: Windows uses PADATA 15 for the request too
|
||||
|
||||
* extra.c: add heim_any_cmp
|
||||
|
||||
* der_put.c: implement UTCtime correctly
|
||||
|
||||
* der_locl.h: remove #ifdef HAVE_TIMEGM\ntimegm\n#endif here from
|
||||
der.h so one day der.h can get installed
|
||||
|
||||
* der_length.c: implement UTCtime correctly
|
||||
|
||||
* der_get.c: implement UTCtime correctly, prefix dce_fix with
|
||||
_heim_fix
|
||||
|
||||
* der_copy.c: make copy_bit_string work again
|
||||
|
||||
* der_cmp.c: add octet_string, integer, bit_string cmp functions
|
||||
|
||||
* der.h: hide away more symbols, add more _cmp functions
|
||||
|
||||
2004-03-06 Love <lha@stacken.kth.se>
|
||||
|
||||
* Makefile.am: add more pkix types make k5 use rfc150 bitstrings,
|
||||
everything else use der bitstrings
|
||||
|
||||
* main.c: as a compile time option, handle no rfc1510 bitstrings
|
||||
|
||||
* gen_locl.h: rfc1510 bitstrings flag
|
||||
|
||||
* gen_length.c: as a compile time option, handle no rfc1510
|
||||
bitstrings
|
||||
|
||||
* gen_encode.c: as a compile time option, handle no rfc1510
|
||||
bitstrings
|
||||
|
||||
* gen_decode.c: handle no rfc1510 bitstrings
|
||||
|
||||
* check-gen.c: test for bitstrings
|
||||
|
||||
* rfc2459.asn1: add Certificates and KeyUsage
|
||||
|
||||
2004-02-22 Love <lha@stacken.kth.se>
|
||||
|
||||
* pkinit.asn1: use Name from PKIX
|
||||
|
||||
* rfc2459.asn1: add more silly string types to DirectoryString
|
||||
|
||||
* gen_encode.c: add checks for data overflow when encoding
|
||||
TBitString with members encode SET OF correctly by bytewise
|
||||
sorting the members
|
||||
|
||||
* gen_decode.c: add checks for data overrun when encoding
|
||||
TBitString with members
|
||||
|
||||
* der_put.c: add _heim_der_set_sort
|
||||
|
||||
* der_cmp.c: rename oid_cmp to heim_oid_cmp
|
||||
|
||||
* der.h: rename oid_cmp to heim_oid_cmp, add _heim_der_set_sort
|
||||
|
||||
* check-gen.c: add check for Name and (commented out) heim_integer
|
||||
|
||||
* check-der.c: test for "der_length.c: Fix len_unsigned for
|
||||
certain negative integers, it got the length wrong" , from
|
||||
Panasas, Inc.
|
||||
|
||||
* der_length.c: Fix len_unsigned for certain negative integers, it
|
||||
got the length wrong, fix from Panasas, Inc.
|
||||
|
||||
rename len_int and len_unsigned to _heim_\&
|
||||
|
||||
* gen_length.c: 1.14: (length_type): TSequenceOf: add up the size
|
||||
of all the elements, don't use just the size of the last element.
|
||||
|
||||
2004-02-20 Love <lha@stacken.kth.se>
|
||||
|
||||
* rfc2459.asn1: include defintion of Name
|
||||
|
||||
* pkinit.asn1: no need for ContentType, its cms internal
|
||||
|
||||
* CMS.asn1: move ContentInfo to CMS
|
||||
|
||||
* pkinit.asn1: update to pk-init-18, move ContentInfo to CMS
|
||||
|
||||
* Makefile.am: align with pk-init-18, move contentinfo to cms
|
||||
|
||||
2004-02-17 Love <lha@stacken.kth.se>
|
||||
|
||||
* der_get.c: rewrite previous commit
|
||||
|
||||
* der_get.c (der_get_heim_integer): handle positive integer
|
||||
starting with 0
|
||||
|
||||
* der_length.c (der_put_heim_integer): try handle negative
|
||||
integers better (?)
|
||||
|
||||
* der_put.c (der_put_heim_integer): try handle negative integers
|
||||
better
|
||||
|
||||
* der_get.c (der_get_heim_integer): dont abort on negative integer just
|
||||
return ASN1_OVERRUN for now
|
||||
|
||||
* parse.y: add ia5string, and printablestring
|
||||
|
||||
* gen_length.c: add ia5string, and printablestring
|
||||
|
||||
* gen_free.c: add ia5string, and printablestring
|
||||
|
||||
* gen_decode.c: add ia5string, and printablestring
|
||||
|
||||
* gen_copy.c: add ia5string, and printablestring
|
||||
|
||||
* gen.c: add ia5string, printablestring, and utf8string change
|
||||
implemetation of heim_integer and store the data as bigendian byte
|
||||
array with a external flag for signedness
|
||||
|
||||
* der_put.c: add ia5string, printablestring, and utf8string change
|
||||
implemetation of heim_integer and store the data as bigendian byte
|
||||
array with a external flag for signedness
|
||||
|
||||
* der_length.c: add ia5string, printablestring, and utf8string
|
||||
change implemetation of heim_integer and store the data as
|
||||
bigendian byte array with a external flag for signedness
|
||||
|
||||
* der_get.c: add ia5string, printablestring, and utf8string change
|
||||
implemetation of heim_integer and store the data as bigendian byte
|
||||
array with a external flag for signedness
|
||||
|
||||
* der_free.c: add ia5string, printablestring, and utf8string
|
||||
|
||||
* der_copy.c: add ia5string, printablestring, and utf8string
|
||||
|
||||
* der.h: add ia5string, printablestring, and utf8string
|
||||
|
||||
* asn1-common.h: add signedness flag to heim_integer, add
|
||||
ia5string and printablestring
|
||||
|
||||
2004-02-13 Love <lha@stacken.kth.se>
|
||||
|
||||
* rfc2459.asn1: use BIGINTEGER where appropriate
|
||||
|
||||
* setchgpw2.asn1: spelling and add op-req again
|
||||
|
||||
2004-02-12 Love <lha@stacken.kth.se>
|
||||
|
||||
* Makefile.am: clean up better
|
||||
|
||||
2004-02-11 Love <lha@stacken.kth.se>
|
||||
|
||||
* gen_decode.c (decode_type): TTag, don't overshare the reallen
|
||||
variable
|
||||
|
||||
* Makefile.am: adapt to log file name change
|
||||
|
||||
* gen.c: genereate log file name based on base name
|
||||
|
||||
2003-11-26 Love <lha@stacken.kth.se>
|
||||
|
||||
* Makefile.am: += asn1_AlgorithmIdentifierNonOpt.x
|
||||
|
||||
* rfc2459.asn1: add AlgorithmIdentifierNonOpt and use it where
|
||||
it's needed, make DomainParameters.validationParms heim_any as a
|
||||
hack. Both are workarounds for the problem with heimdal's asn1
|
||||
compiler have with decoing context tagless OPTIONALs.
|
||||
|
||||
* pkinit.asn1: don't import AlgorithmIdentifier
|
||||
|
||||
2003-11-25 Love <lha@stacken.kth.se>
|
||||
|
||||
* der_put.c (der_put_bit_string): make it work somewhat better
|
||||
(should really prune off all trailing zeros)
|
||||
|
||||
* gen_encode.c (encode_type): bit string is not a constructed type
|
||||
|
||||
* der_length.c (length_bit_string): calculate right length for
|
||||
bitstrings
|
||||
|
||||
2003-11-24 Love <lha@stacken.kth.se>
|
||||
|
||||
* der_cmp.c (oid_cmp): compare the whole array, not just
|
||||
length/sizeof(component)
|
||||
|
||||
* check-common.c: mmap the scratch areas, mprotect before and
|
||||
after, align data to the edge of the mprotect()ed area to provoke
|
||||
bugs
|
||||
|
||||
* Makefile.am: add DomainParameters, ValidationParms
|
||||
|
||||
* rfc2459.asn1: add DomainParameters, ValidationParms
|
||||
|
||||
* check-der.c: add free function
|
||||
|
||||
* check-common.h: add free function
|
||||
|
||||
* check-common.c: add free function
|
||||
|
||||
* check-gen.c: check KRB-ERROR
|
||||
|
||||
* asn1_print.c: check end of tag_names loop into APPL class tags
|
||||
|
||||
2003-11-23 Love <lha@stacken.kth.se>
|
||||
|
||||
* der_put.c (der_put_generalized_time): check size, not *size
|
||||
|
||||
2003-11-11 Love <lha@stacken.kth.se>
|
||||
|
||||
* gen_decode.c (decode_type/TBitString): skip over
|
||||
skipped-bits-in-last-octet octet
|
||||
|
||||
* gen_glue.c (generate_units): generate units in reverse order to
|
||||
keep unparse_units happy
|
||||
|
||||
2003-11-08 Love <lha@stacken.kth.se>
|
||||
|
||||
* Makefile.am: generate all silly pkinit files
|
||||
|
||||
* pkinit.asn1: make it work again, add strange ms structures
|
||||
|
||||
* k5.asn1: PROV-SRV-LOCATION, PacketCable provisioning server
|
||||
location, PKT-SP-SEC-I09-030728
|
||||
|
||||
* asn1-common.h: add bit string
|
||||
|
||||
* der_put.c: add bit string and utctime
|
||||
|
||||
* gen.c: add bit string and utctime
|
||||
|
||||
* gen_copy.c: add bit string and utctime
|
||||
|
||||
* der_copy.c: add bit string
|
||||
|
||||
* gen_decode.c: add utctime and bitstring
|
||||
|
||||
* gen_encode.c: add utctime and bitstring
|
||||
|
||||
* gen_free.c: add utctime and bitstring
|
||||
|
||||
* gen_glue.c: don't generate glue for member-less bit strings
|
||||
|
||||
* der_cmp.c: compare function for oids
|
||||
|
||||
* gen_length.c: add utc time, make bit string work for bits
|
||||
strings w/o any members
|
||||
|
||||
* der_cmp.c: compare function for oids
|
||||
|
||||
* der.h: update boolean prototypes add utctime and bit_string
|
||||
|
||||
* der_free.c: add free_bit_string
|
||||
|
||||
* der_get.c: add bit string and utctime
|
||||
|
||||
* der_length.c: add bit string and utctime, fix memory leak in
|
||||
length_generalized_time
|
||||
|
||||
* CMS.asn1: make EncryptedContentInfo.encryptedContent a OCTET
|
||||
STRING to make the generator do the right thing with IMPLICIT
|
||||
mumble OPTIONAL, make CertificateSet a heim_any_set
|
||||
|
||||
* extra.c, heim_asn1.h: add any_set, instead of just consuming one
|
||||
der object, its consumes the rest of the data avaible
|
||||
|
||||
* extra.c, heim_asn1.h: extern implementation of ANY, decoder
|
||||
needs to have hack removed when generator handles tagless optional
|
||||
data
|
||||
|
||||
* pkinit.asn1: add KdcDHKeyInfo-Win2k
|
||||
|
||||
2003-11-07 Love H<>rnquist <20>strand <lha@it.su.se>
|
||||
|
||||
* der_copy.c (copy_oid): copy all components
|
||||
|
||||
* parse.y: parse UTCTime, allow multiple IMPORT
|
||||
|
||||
* symbol.h: add TUTCTime
|
||||
|
||||
* rfc2459.asn1: update
|
||||
|
||||
* x509.asn1: update
|
||||
|
||||
* pkinit.asn1: update
|
||||
|
||||
* CMS.asn1: new file
|
||||
|
||||
* asn1_print.c: print some more lengths, check length before
|
||||
steping out in the void, parse SET, only go down CONTEXT of type
|
||||
CONS (not PRIM)
|
||||
|
||||
2003-09-17 Love H<>rnquist <20>strand <lha@it.su.se>
|
||||
|
||||
* gen_encode.c (TChoice, TSequence): code element in reverse
|
||||
order...
|
||||
|
||||
2003-09-16 Love H<>rnquist <20>strand <lha@it.su.se>
|
||||
|
||||
* gen.c: store NULL's as int's for now
|
||||
|
||||
* parse.y: remove dup of type def of UsefulType
|
||||
|
||||
2003-09-11 Love H<>rnquist <20>strand <lha@it.su.se>
|
||||
|
||||
* gen_decode.c (decode_type): if malloc failes, return ENOMEM
|
||||
|
||||
2003-09-10 Love H<>rnquist <20>strand <lha@it.su.se>
|
||||
|
||||
* parse.y: kw_UTF8String is a token put tag around the OID
|
||||
|
||||
* asn1_print.c (UT_Integer): when the integer is larger then int
|
||||
can handle, just print BIG INT and its size
|
||||
|
||||
2003-09-10 Love H<>rnquist <20>strand <lha@it.su.se>
|
||||
|
||||
* gen_decode.c (decode_type): TTag, try to generate prettier code
|
||||
in the non optional case, also remember to update length
|
||||
|
||||
2003-01-22 Johan Danielsson <joda@pdc.kth.se>
|
||||
|
||||
* gen_decode.c: add flag to decode broken DCE BER encoding
|
||||
|
||||
* gen_locl.h: add flag to decode broken DCE BER encoding
|
||||
|
||||
* main.c: add flag to decode broken DCE BER encoding
|
||||
|
@@ -2,98 +2,329 @@
|
||||
|
||||
include $(top_srcdir)/Makefile.am.common
|
||||
|
||||
YFLAGS = -d
|
||||
YFLAGS = -dt
|
||||
|
||||
lib_LTLIBRARIES = libasn1.la
|
||||
libasn1_la_LDFLAGS = -version-info 7:0:1
|
||||
libasn1_la_LDFLAGS = -version-info 6:1:1
|
||||
|
||||
libasn1_la_LIBADD = $(LIB_com_err)
|
||||
libasn1_la_LIBADD = @LIB_com_err@
|
||||
|
||||
BUILT_SOURCES = \
|
||||
$(gen_files:.x=.c) \
|
||||
asn1_err.h \
|
||||
BUILT_SOURCES = \
|
||||
$(gen_files_rfc2459:.x=.c) \
|
||||
$(gen_files_cms:.x=.c) \
|
||||
$(gen_files_k5:.x=.c) \
|
||||
$(gen_files_pkinit:.x=.c) \
|
||||
$(gen_files_pkcs8:.x=.c) \
|
||||
$(gen_files_pkcs9:.x=.c) \
|
||||
$(gen_files_pkcs12:.x=.c) \
|
||||
asn1_err.h \
|
||||
asn1_err.c
|
||||
|
||||
gen_files = \
|
||||
asn1_AD_AND_OR.x \
|
||||
asn1_AD_IF_RELEVANT.x \
|
||||
asn1_AD_KDCIssued.x \
|
||||
asn1_AD_MANDATORY_FOR_KDC.x \
|
||||
asn1_APOptions.x \
|
||||
asn1_AP_REP.x \
|
||||
asn1_AP_REQ.x \
|
||||
asn1_AS_REP.x \
|
||||
asn1_AS_REQ.x \
|
||||
asn1_Authenticator.x \
|
||||
asn1_AuthorizationData.x \
|
||||
asn1_AUTHDATA_TYPE.x \
|
||||
asn1_CBCParameter.x \
|
||||
asn1_CKSUMTYPE.x \
|
||||
asn1_ChangePasswdDataMS.x \
|
||||
asn1_Checksum.x \
|
||||
asn1_ENCTYPE.x \
|
||||
asn1_ETYPE_INFO.x \
|
||||
asn1_ETYPE_INFO2.x \
|
||||
asn1_ETYPE_INFO2_ENTRY.x \
|
||||
asn1_ETYPE_INFO_ENTRY.x \
|
||||
asn1_EncAPRepPart.x \
|
||||
asn1_EncASRepPart.x \
|
||||
asn1_EncKDCRepPart.x \
|
||||
asn1_EncKrbCredPart.x \
|
||||
asn1_EncKrbPrivPart.x \
|
||||
asn1_EncTGSRepPart.x \
|
||||
asn1_EncTicketPart.x \
|
||||
asn1_EncryptedData.x \
|
||||
asn1_EncryptionKey.x \
|
||||
asn1_EtypeList.x \
|
||||
asn1_HostAddress.x \
|
||||
asn1_HostAddresses.x \
|
||||
asn1_KDCOptions.x \
|
||||
asn1_KDC_REP.x \
|
||||
asn1_KDC_REQ.x \
|
||||
asn1_KDC_REQ_BODY.x \
|
||||
asn1_KRB_CRED.x \
|
||||
asn1_KRB_ERROR.x \
|
||||
asn1_KRB_PRIV.x \
|
||||
asn1_KRB_SAFE.x \
|
||||
asn1_KRB_SAFE_BODY.x \
|
||||
asn1_KerberosString.x \
|
||||
asn1_KerberosTime.x \
|
||||
asn1_KrbCredInfo.x \
|
||||
asn1_LR_TYPE.x \
|
||||
asn1_LastReq.x \
|
||||
asn1_MESSAGE_TYPE.x \
|
||||
asn1_METHOD_DATA.x \
|
||||
asn1_NAME_TYPE.x \
|
||||
asn1_PADATA_TYPE.x \
|
||||
asn1_PA_DATA.x \
|
||||
asn1_PA_ENC_SAM_RESPONSE_ENC.x \
|
||||
asn1_PA_ENC_TS_ENC.x \
|
||||
asn1_PA_PAC_REQUEST.x \
|
||||
asn1_PA_SAM_CHALLENGE_2.x \
|
||||
asn1_PA_SAM_CHALLENGE_2_BODY.x \
|
||||
asn1_PA_SAM_REDIRECT.x \
|
||||
asn1_PA_SAM_RESPONSE_2.x \
|
||||
asn1_PA_SAM_TYPE.x \
|
||||
asn1_Principal.x \
|
||||
asn1_PrincipalName.x \
|
||||
asn1_RC2CBCParameter.x \
|
||||
asn1_Realm.x \
|
||||
asn1_SAMFlags.x \
|
||||
asn1_TGS_REP.x \
|
||||
asn1_TGS_REQ.x \
|
||||
asn1_Ticket.x \
|
||||
asn1_TicketFlags.x \
|
||||
asn1_TransitedEncoding.x \
|
||||
asn1_UNSIGNED.x
|
||||
gen_files_k5 = \
|
||||
asn1_AD_AND_OR.x \
|
||||
asn1_AD_IF_RELEVANT.x \
|
||||
asn1_AD_KDCIssued.x \
|
||||
asn1_AD_MANDATORY_FOR_KDC.x \
|
||||
asn1_APOptions.x \
|
||||
asn1_AP_REP.x \
|
||||
asn1_AP_REQ.x \
|
||||
asn1_AS_REP.x \
|
||||
asn1_AS_REQ.x \
|
||||
asn1_AUTHDATA_TYPE.x \
|
||||
asn1_Authenticator.x \
|
||||
asn1_AuthorizationData.x \
|
||||
asn1_CKSUMTYPE.x \
|
||||
asn1_ChangePasswdDataMS.x \
|
||||
asn1_Checksum.x \
|
||||
asn1_ENCTYPE.x \
|
||||
asn1_ETYPE_INFO.x \
|
||||
asn1_ETYPE_INFO2.x \
|
||||
asn1_ETYPE_INFO2_ENTRY.x \
|
||||
asn1_ETYPE_INFO_ENTRY.x \
|
||||
asn1_EncAPRepPart.x \
|
||||
asn1_EncASRepPart.x \
|
||||
asn1_EncKDCRepPart.x \
|
||||
asn1_EncKrbCredPart.x \
|
||||
asn1_EncKrbPrivPart.x \
|
||||
asn1_EncTGSRepPart.x \
|
||||
asn1_EncTicketPart.x \
|
||||
asn1_EncryptedData.x \
|
||||
asn1_EncryptionKey.x \
|
||||
asn1_EtypeList.x \
|
||||
asn1_HostAddress.x \
|
||||
asn1_HostAddresses.x \
|
||||
asn1_KDCOptions.x \
|
||||
asn1_KDC_REP.x \
|
||||
asn1_KDC_REQ.x \
|
||||
asn1_KDC_REQ_BODY.x \
|
||||
asn1_KRB_CRED.x \
|
||||
asn1_KRB_ERROR.x \
|
||||
asn1_KRB_PRIV.x \
|
||||
asn1_KRB_SAFE.x \
|
||||
asn1_KRB_SAFE_BODY.x \
|
||||
asn1_krb5int32.x \
|
||||
asn1_krb5uint32.x \
|
||||
asn1_KerberosString.x \
|
||||
asn1_KerberosTime.x \
|
||||
asn1_KrbCredInfo.x \
|
||||
asn1_LR_TYPE.x \
|
||||
asn1_LastReq.x \
|
||||
asn1_MESSAGE_TYPE.x \
|
||||
asn1_METHOD_DATA.x \
|
||||
asn1_NAME_TYPE.x \
|
||||
asn1_PADATA_TYPE.x \
|
||||
asn1_PA_DATA.x \
|
||||
asn1_PA_ENC_SAM_RESPONSE_ENC.x \
|
||||
asn1_PA_ENC_TS_ENC.x \
|
||||
asn1_PA_SAM_CHALLENGE_2.x \
|
||||
asn1_PA_SAM_CHALLENGE_2_BODY.x \
|
||||
asn1_PA_SAM_REDIRECT.x \
|
||||
asn1_PA_SAM_RESPONSE_2.x \
|
||||
asn1_PA_SAM_TYPE.x \
|
||||
asn1_PA_PAC_REQUEST.x \
|
||||
asn1_PROV_SRV_LOCATION.x \
|
||||
asn1_Principal.x \
|
||||
asn1_PrincipalName.x \
|
||||
asn1_Realm.x \
|
||||
asn1_SAMFlags.x \
|
||||
asn1_TGS_REP.x \
|
||||
asn1_TGS_REQ.x \
|
||||
asn1_TYPED_DATA.x \
|
||||
asn1_Ticket.x \
|
||||
asn1_TicketFlags.x \
|
||||
asn1_TransitedEncoding.x \
|
||||
asn1_TypedData.x \
|
||||
asn1_RC2CBCParameter.x \
|
||||
asn1_CBCParameter.x
|
||||
|
||||
gen_files_cms = \
|
||||
asn1_id_pkcs7.x \
|
||||
asn1_id_pkcs7_data.x \
|
||||
asn1_id_pkcs7_signedData.x \
|
||||
asn1_id_pkcs7_signedAndEnvelopedData.x \
|
||||
asn1_id_pkcs7_envelopedData.x \
|
||||
asn1_id_pkcs7_digestedData.x \
|
||||
asn1_id_pkcs7_encryptedData.x \
|
||||
asn1_CMSCBCParameter.x \
|
||||
asn1_CMSEncryptedData.x \
|
||||
asn1_CMSRC2CBCParameter.x \
|
||||
asn1_CMSVersion.x \
|
||||
asn1_CMSIdentifier.x \
|
||||
asn1_CertificateList.x \
|
||||
asn1_CertificateRevocationLists.x \
|
||||
asn1_CertificateSet.x \
|
||||
asn1_CertificateSetReal.x \
|
||||
asn1_ContentEncryptionAlgorithmIdentifier.x \
|
||||
asn1_ContentInfo.x \
|
||||
asn1_ContentType.x \
|
||||
asn1_DigestAlgorithmIdentifier.x \
|
||||
asn1_DigestAlgorithmIdentifiers.x \
|
||||
asn1_EncapsulatedContentInfo.x \
|
||||
asn1_EncryptedContent.x \
|
||||
asn1_EncryptedContentInfo.x \
|
||||
asn1_EncryptedKey.x \
|
||||
asn1_EnvelopedData.x \
|
||||
asn1_IssuerAndSerialNumber.x \
|
||||
asn1_KeyEncryptionAlgorithmIdentifier.x \
|
||||
asn1_KeyTransRecipientInfo.x \
|
||||
asn1_OriginatorInfo.x \
|
||||
asn1_RecipientIdentifier.x \
|
||||
asn1_RecipientInfo.x \
|
||||
asn1_RecipientInfos.x \
|
||||
asn1_SignatureAlgorithmIdentifier.x \
|
||||
asn1_SignatureValue.x \
|
||||
asn1_SignedAttributes.x \
|
||||
asn1_SignedData.x \
|
||||
asn1_SignerIdentifier.x \
|
||||
asn1_SignerInfo.x \
|
||||
asn1_SignerInfos.x \
|
||||
asn1_UnprotectedAttributes.x \
|
||||
asn1_UnsignedAttributes.x
|
||||
|
||||
gen_files_rfc2459 = \
|
||||
asn1_Version.x \
|
||||
asn1_id_pkcs_1.x \
|
||||
asn1_id_pkcs1_rsaEncryption.x \
|
||||
asn1_id_pkcs1_md2WithRSAEncryption.x \
|
||||
asn1_id_pkcs1_md5WithRSAEncryption.x \
|
||||
asn1_id_pkcs1_sha1WithRSAEncryption.x \
|
||||
asn1_id_pkcs_2.x \
|
||||
asn1_id_pkcs2_md2.x \
|
||||
asn1_id_pkcs2_md4.x \
|
||||
asn1_id_pkcs2_md5.x \
|
||||
asn1_id_pkcs_3.x \
|
||||
asn1_id_pkcs3_rc2_cbc.x \
|
||||
asn1_id_pkcs3_rc4.x \
|
||||
asn1_id_pkcs3_des_ede3_cbc.x \
|
||||
asn1_id_rsadsi_encalg.x \
|
||||
asn1_id_rsadsi_des_ede3_cbc.x \
|
||||
asn1_id_secsig_sha_1.x \
|
||||
asn1_id_nit_aes_algs.x \
|
||||
asn1_id_aes_128_cbc.x \
|
||||
asn1_id_aes_192_cbc.x \
|
||||
asn1_id_aes_256_cbc.x \
|
||||
asn1_id_dhpublicnumber.x \
|
||||
asn1_id_x509_ce.x \
|
||||
asn1_AlgorithmIdentifier.x \
|
||||
asn1_AttributeType.x \
|
||||
asn1_AttributeValue.x \
|
||||
asn1_TeletexStringx.x \
|
||||
asn1_DirectoryString.x \
|
||||
asn1_Attribute.x \
|
||||
asn1_AttributeTypeAndValue.x \
|
||||
asn1_RelativeDistinguishedName.x \
|
||||
asn1_RDNSequence.x \
|
||||
asn1_Name.x \
|
||||
asn1_CertificateSerialNumber.x \
|
||||
asn1_Time.x \
|
||||
asn1_Validity.x \
|
||||
asn1_UniqueIdentifier.x \
|
||||
asn1_SubjectPublicKeyInfo.x \
|
||||
asn1_Extension.x \
|
||||
asn1_Extensions.x \
|
||||
asn1_TBSCertificate.x \
|
||||
asn1_Certificate.x \
|
||||
asn1_Certificates.x \
|
||||
asn1_ValidationParms.x \
|
||||
asn1_DomainParameters.x \
|
||||
asn1_OtherName.x \
|
||||
asn1_GeneralName.x \
|
||||
asn1_GeneralNames.x \
|
||||
asn1_id_x509_ce_keyUsage.x \
|
||||
asn1_KeyUsage.x \
|
||||
asn1_id_x509_ce_authorityKeyIdentifier.x \
|
||||
asn1_KeyIdentifier.x \
|
||||
asn1_AuthorityKeyIdentifier.x \
|
||||
asn1_id_x509_ce_subjectKeyIdentifier.x \
|
||||
asn1_SubjectKeyIdentifier.x \
|
||||
asn1_id_x509_ce_basicConstraints.x \
|
||||
asn1_BasicConstraints.x \
|
||||
asn1_id_x509_ce_nameConstraints.x \
|
||||
asn1_BaseDistance.x \
|
||||
asn1_GeneralSubtree.x \
|
||||
asn1_GeneralSubtrees.x \
|
||||
asn1_NameConstraints.x \
|
||||
asn1_id_x509_ce_privateKeyUsagePeriod.x \
|
||||
asn1_id_x509_ce_certificatePolicies.x \
|
||||
asn1_id_x509_ce_policyMappings.x \
|
||||
asn1_id_x509_ce_subjectAltName.x \
|
||||
asn1_id_x509_ce_issuerAltName.x \
|
||||
asn1_id_x509_ce_subjectDirectoryAttributes.x \
|
||||
asn1_id_x509_ce_policyConstraints.x \
|
||||
asn1_id_x509_ce_extKeyUsage.x \
|
||||
asn1_id_x509_ce_cRLDistributionPoints.x \
|
||||
asn1_id_x509_ce_cRLNumber.x \
|
||||
asn1_id_x509_ce_deltaCRLIndicator.x \
|
||||
asn1_id_x509_ce_issuingDistributionPoint.x \
|
||||
asn1_id_x509_ce_cRLReasons.x \
|
||||
asn1_id_x509_ce_holdInstructionCode.x \
|
||||
asn1_id_x509_ce_invalidityDate.x \
|
||||
asn1_id_x509_ce_certificateIssuer.x \
|
||||
asn1_id_x509_ce_inhibitAnyPolicy.x \
|
||||
asn1_id_x509_ce_freshestCRL.x \
|
||||
asn1_DSASigValue.x \
|
||||
asn1_DSAPublicKey.x \
|
||||
asn1_DSAParams.x \
|
||||
asn1_RSAPublicKey.x \
|
||||
asn1_DigestInfo.x
|
||||
|
||||
|
||||
gen_files_pkinit = \
|
||||
asn1_id_pkinit.x \
|
||||
asn1_id_pkauthdata.x \
|
||||
asn1_id_pkdhkeydata.x \
|
||||
asn1_id_pkrkeydata.x \
|
||||
asn1_id_pkekuoid.x \
|
||||
asn1_id_pkkdcekuoid.x \
|
||||
asn1_DHNonce.x \
|
||||
asn1_TrustedCA.x \
|
||||
asn1_PA_PK_AS_REQ.x \
|
||||
asn1_PKAuthenticator.x \
|
||||
asn1_AuthPack.x \
|
||||
asn1_TD_TRUSTED_CERTIFIERS.x \
|
||||
asn1_TD_INVALID_CERTIFICATES.x \
|
||||
asn1_KRB5PrincipalName.x \
|
||||
asn1_AD_INITIAL_VERIFIED_CAS.x \
|
||||
asn1_DHRepInfo.x \
|
||||
asn1_PA_PK_AS_REP.x \
|
||||
asn1_KDCDHKeyInfo.x \
|
||||
asn1_ReplyKeyPack.x \
|
||||
asn1_TD_DH_PARAMETERS.x \
|
||||
asn1_PKAuthenticator_Win2k.x \
|
||||
asn1_AuthPack_Win2k.x \
|
||||
asn1_PA_PK_AS_REP_Win2k.x \
|
||||
asn1_KDCDHKeyInfo_Win2k.x \
|
||||
asn1_TrustedCA_19.x \
|
||||
asn1_PA_PK_AS_REQ_19.x \
|
||||
asn1_PA_PK_AS_REQ_Win2k.x \
|
||||
asn1_PKAuthenticator_19.x \
|
||||
asn1_AuthPack_19.x \
|
||||
asn1_PA_PK_AS_REP_19.x \
|
||||
asn1_ReplyKeyPack_19.x
|
||||
|
||||
|
||||
gen_files_pkcs12 = \
|
||||
asn1_id_pkcs_12.x \
|
||||
asn1_id_pkcs_12PbeIds.x \
|
||||
asn1_id_pbeWithSHAAnd128BitRC4.x \
|
||||
asn1_id_pbeWithSHAAnd40BitRC4.x \
|
||||
asn1_id_pbeWithSHAAnd3_KeyTripleDES_CBC.x \
|
||||
asn1_id_pbeWithSHAAnd2_KeyTripleDES_CBC.x \
|
||||
asn1_id_pbeWithSHAAnd128BitRC2_CBC.x \
|
||||
asn1_id_pbewithSHAAnd40BitRC2_CBC.x \
|
||||
asn1_id_pkcs12_bagtypes.x \
|
||||
asn1_id_pkcs12_keyBag.x \
|
||||
asn1_id_pkcs12_pkcs8ShroudedKeyBag.x \
|
||||
asn1_id_pkcs12_certBag.x \
|
||||
asn1_id_pkcs12_crlBag.x \
|
||||
asn1_id_pkcs12_secretBag.x \
|
||||
asn1_id_pkcs12_safeContentsBag.x \
|
||||
asn1_PKCS12_MacData.x \
|
||||
asn1_PKCS12_PFX.x \
|
||||
asn1_PKCS12_AuthenticatedSafe.x \
|
||||
asn1_PKCS12_CertBag.x \
|
||||
asn1_PKCS12_Attribute.x \
|
||||
asn1_PKCS12_Attributes.x \
|
||||
asn1_PKCS12_SafeBag.x \
|
||||
asn1_PKCS12_SafeContents.x \
|
||||
asn1_PKCS12_PBEParams.x
|
||||
|
||||
gen_files_pkcs8 = \
|
||||
asn1_PKCS8PrivateKeyAlgorithmIdentifier.x \
|
||||
asn1_PKCS8PrivateKey.x \
|
||||
asn1_PKCS8PrivateKeyInfo.x \
|
||||
asn1_PKCS8Attributes.x \
|
||||
asn1_PKCS8EncryptedPrivateKeyInfo.x \
|
||||
asn1_PKCS8EncryptedData.x
|
||||
|
||||
gen_files_pkcs9 = \
|
||||
asn1_id_pkcs_9.x \
|
||||
asn1_id_pkcs_9_at_friendlyName.x \
|
||||
asn1_id_pkcs_9_at_localKeyId.x \
|
||||
asn1_id_pkcs_9_at_certTypes.x \
|
||||
asn1_id_pkcs_9_at_certTypes_x509.x \
|
||||
asn1_PKCS9_BMPString.x \
|
||||
asn1_PKCS9_friendlyName.x
|
||||
|
||||
gen_files_test = \
|
||||
asn1_TESTChoice1.x \
|
||||
asn1_TESTChoice2.x \
|
||||
asn1_TESTSeq.x \
|
||||
asn1_TESTLargeTag.x
|
||||
|
||||
noinst_PROGRAMS = asn1_compile asn1_print asn1_gen
|
||||
|
||||
noinst_PROGRAMS = asn1_compile asn1_print
|
||||
check_PROGRAMS = check-der check-gen
|
||||
TESTS = check-der check-gen
|
||||
|
||||
check_der_SOURCES = check-der.c check-common.c
|
||||
check_gen_SOURCES = check-gen.c check-common.c
|
||||
asn1_gen_SOURCES = asn1_gen.c
|
||||
asn1_print_SOURCES = asn1_print.c
|
||||
|
||||
check_der_SOURCES = check-der.c check-common.c
|
||||
check_gen_SOURCES = \
|
||||
check-gen.c \
|
||||
check-common.c \
|
||||
$(gen_files_test:.x=.c)
|
||||
|
||||
asn1_compile_SOURCES = \
|
||||
gen.c \
|
||||
@@ -110,12 +341,14 @@ asn1_compile_SOURCES = \
|
||||
symbol.c
|
||||
|
||||
libasn1_la_SOURCES = \
|
||||
der.c \
|
||||
der_get.c \
|
||||
der_put.c \
|
||||
der_free.c \
|
||||
der_length.c \
|
||||
der_copy.c \
|
||||
der_cmp.c \
|
||||
extra.c \
|
||||
timegm.c \
|
||||
$(BUILT_SOURCES)
|
||||
|
||||
@@ -128,22 +361,78 @@ check_der_LDADD = \
|
||||
|
||||
check_gen_LDADD = $(check_der_LDADD)
|
||||
asn1_print_LDADD = $(check_der_LDADD)
|
||||
asn1_gen_LDADD = $(check_der_LDADD)
|
||||
|
||||
CLEANFILES = lex.c parse.c parse.h krb5_asn1.h \
|
||||
CLEANFILES = lex.c parse.c parse.h \
|
||||
$(BUILT_SOURCES) \
|
||||
$(gen_files) asn1_files asn1_files2
|
||||
$(gen_files_rfc2459) \
|
||||
$(gen_files_cms) \
|
||||
$(gen_files_k5) \
|
||||
$(gen_files_pkinit) \
|
||||
$(gen_files_pkcs8) \
|
||||
$(gen_files_pkcs9) \
|
||||
$(gen_files_pkcs12) \
|
||||
$(gen_files_test) \
|
||||
rfc2459_asn1_files rfc2459_asn1.h \
|
||||
cms_asn1_files cms_asn1.h \
|
||||
krb5_asn1_files krb5_asn1.h \
|
||||
pkinit_asn1_files pkinit_asn1.h \
|
||||
pkcs8_asn1_files pkcs8_asn1.h \
|
||||
pkcs9_asn1_files pkcs9_asn1.h \
|
||||
pkcs12_asn1_files pkcs12_asn1.h \
|
||||
test_asn1_files test_asn1.h
|
||||
|
||||
include_HEADERS = krb5_asn1.h asn1_err.h der.h
|
||||
|
||||
include_HEADERS = asn1_err.h der.h heim_asn1.h
|
||||
include_HEADERS += krb5_asn1.h
|
||||
include_HEADERS += pkinit_asn1.h
|
||||
include_HEADERS += cms_asn1.h
|
||||
include_HEADERS += rfc2459_asn1.h
|
||||
include_HEADERS += pkcs8_asn1.h
|
||||
include_HEADERS += pkcs9_asn1.h
|
||||
include_HEADERS += pkcs12_asn1.h
|
||||
|
||||
$(asn1_compile_OBJECTS): parse.h parse.c
|
||||
|
||||
$(gen_files) krb5_asn1.h: asn1_files
|
||||
$(gen_files_k5) krb5_asn1.h: krb5_asn1_files
|
||||
$(gen_files_pkinit) pkinit_asn1.h: pkinit_asn1_files
|
||||
$(gen_files_pkcs8) pkcs8_asn1.h: pkcs8_asn1_files
|
||||
$(gen_files_pkcs9) pkcs9_asn1.h: pkcs9_asn1_files
|
||||
$(gen_files_pkcs12) pkcs12_asn1.h: pkcs12_asn1_files
|
||||
$(gen_files_rfc2459) rfc2459_asn1.h: rfc2459_asn1_files
|
||||
$(gen_files_cms) cms_asn1.h: cms_asn1_files
|
||||
$(gen_files_test) test_asn1.h: test_asn1_files
|
||||
|
||||
asn1_files: asn1_compile$(EXEEXT) $(srcdir)/k5.asn1
|
||||
./asn1_compile$(EXEEXT) $(srcdir)/k5.asn1 krb5_asn1
|
||||
rfc2459_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/rfc2459.asn1
|
||||
./asn1_compile$(EXEEXT) --preserve-binary=TBSCertificate --preserve-binary=Name $(srcdir)/rfc2459.asn1 rfc2459_asn1 || (rm -f rfc2459_asn1_files ; exit 1)
|
||||
|
||||
cms_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/CMS.asn1
|
||||
./asn1_compile$(EXEEXT) $(srcdir)/CMS.asn1 cms_asn1 || (rm -f cms_asn1_files ; exit 1)
|
||||
|
||||
krb5_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/k5.asn1
|
||||
./asn1_compile$(EXEEXT) --encode-rfc1510-bit-string $(srcdir)/k5.asn1 krb5_asn1 || (rm -f krb5_asn1_files ; exit 1)
|
||||
|
||||
pkinit_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/pkinit.asn1
|
||||
./asn1_compile$(EXEEXT) $(srcdir)/pkinit.asn1 pkinit_asn1 || (rm -f pkinit_asn1_files ; exit 1)
|
||||
|
||||
pkcs8_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/pkcs8.asn1
|
||||
./asn1_compile$(EXEEXT) $(srcdir)/pkcs8.asn1 pkcs8_asn1 || (rm -f pkcs8_asn1_files ; exit 1)
|
||||
|
||||
pkcs9_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/pkcs9.asn1
|
||||
./asn1_compile$(EXEEXT) $(srcdir)/pkcs9.asn1 pkcs9_asn1 || (rm -f pkcs9_asn1_files ; exit 1)
|
||||
|
||||
pkcs12_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/pkcs12.asn1
|
||||
./asn1_compile$(EXEEXT) $(srcdir)/pkcs12.asn1 pkcs12_asn1 || (rm -f pkcs12_asn1_files ; exit 1)
|
||||
|
||||
test_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/test.asn1
|
||||
./asn1_compile$(EXEEXT) $(srcdir)/test.asn1 test_asn1 || (rm -f test_asn1_files ; exit 1)
|
||||
|
||||
$(libasn1_la_OBJECTS): krb5_asn1.h asn1_err.h
|
||||
|
||||
$(check_gen_OBJECTS): test_asn1.h
|
||||
|
||||
$(asn1_print_OBJECTS): krb5_asn1.h
|
||||
|
||||
parse.h: parse.c
|
||||
|
||||
EXTRA_DIST = asn1_err.et
|
||||
|
@@ -6,6 +6,12 @@
|
||||
#ifndef __asn1_common_definitions__
|
||||
#define __asn1_common_definitions__
|
||||
|
||||
typedef struct heim_integer {
|
||||
size_t length;
|
||||
void *data;
|
||||
int negative;
|
||||
} heim_integer;
|
||||
|
||||
typedef struct heim_octet_string {
|
||||
size_t length;
|
||||
void *data;
|
||||
@@ -13,10 +19,44 @@ typedef struct heim_octet_string {
|
||||
|
||||
typedef char *heim_general_string;
|
||||
typedef char *heim_utf8_string;
|
||||
typedef char *heim_printable_string;
|
||||
typedef char *heim_ia5_string;
|
||||
|
||||
typedef struct heim_bmp_string {
|
||||
size_t length;
|
||||
uint16_t *data;
|
||||
} heim_bmp_string;
|
||||
|
||||
typedef struct heim_universal_string {
|
||||
size_t length;
|
||||
uint32_t *data;
|
||||
} heim_universal_string;
|
||||
|
||||
|
||||
typedef struct heim_oid {
|
||||
size_t length;
|
||||
unsigned *components;
|
||||
} heim_oid;
|
||||
|
||||
typedef struct heim_bit_string {
|
||||
size_t length;
|
||||
void *data;
|
||||
} heim_bit_string;
|
||||
|
||||
#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \
|
||||
do { \
|
||||
(BL) = length_##T((S)); \
|
||||
(B) = malloc((BL)); \
|
||||
if((B) == NULL) { \
|
||||
(R) = ENOMEM; \
|
||||
} else { \
|
||||
(R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \
|
||||
(S), (L)); \
|
||||
if((R) != 0) { \
|
||||
free((B)); \
|
||||
(B) = NULL; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
187
lib/asn1/asn1_gen.c
Normal file
187
lib/asn1/asn1_gen.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "der_locl.h"
|
||||
#include <com_err.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <getarg.h>
|
||||
#include <hex.h>
|
||||
#include <err.h>
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
static int
|
||||
doit(const char *fn)
|
||||
{
|
||||
char buf[2048];
|
||||
char *fnout;
|
||||
const char *bname;
|
||||
unsigned long line = 0;
|
||||
FILE *f, *fout;
|
||||
size_t offset = 0;
|
||||
|
||||
f = fopen(fn, "r");
|
||||
if (f == NULL)
|
||||
err(1, "fopen");
|
||||
|
||||
bname = strrchr(fn, '/');
|
||||
if (bname)
|
||||
bname++;
|
||||
else
|
||||
bname = fn;
|
||||
|
||||
asprintf(&fnout, "%s.out", bname);
|
||||
if (fnout == NULL)
|
||||
errx(1, "malloc");
|
||||
|
||||
fout = fopen(fnout, "w");
|
||||
if (fout == NULL)
|
||||
err(1, "fopen: output file");
|
||||
|
||||
while (fgets(buf, sizeof(buf), f) != NULL) {
|
||||
char *ptr, *class, *type, *tag, *length, *data, *foo;
|
||||
int ret, l, c, ty, ta;
|
||||
unsigned char p[6], *pdata;
|
||||
size_t sz;
|
||||
|
||||
line++;
|
||||
|
||||
buf[strcspn(buf, "\r\n")] = '\0';
|
||||
if (buf[0] == '#' || buf[0] == '\0')
|
||||
continue;
|
||||
|
||||
ptr = buf;
|
||||
while (isspace((unsigned char)*ptr))
|
||||
ptr++;
|
||||
|
||||
class = strtok_r(ptr, " \t\n", &foo);
|
||||
if (class == NULL) errx(1, "class missing one line %lu", line);
|
||||
type = strtok_r(NULL, " \t\n", &foo);
|
||||
if (type == NULL) errx(1, "type missing one line %lu", line);
|
||||
tag = strtok_r(NULL, " \t\n", &foo);
|
||||
if (tag == NULL) errx(1, "tag missing one line %lu", line);
|
||||
length = strtok_r(NULL, " \t\n", &foo);
|
||||
if (length == NULL) errx(1, "length missing one line %lu", line);
|
||||
data = strtok_r(NULL, " \t\n", &foo);
|
||||
|
||||
c = der_get_class_num(class);
|
||||
if (c == -1) errx(1, "no valid class on line %lu", line);
|
||||
ty = der_get_type_num(type);
|
||||
if (ty == -1) errx(1, "no valid type on line %lu", line);
|
||||
ta = der_get_tag_num(tag);
|
||||
if (ta == -1)
|
||||
ta = atoi(tag);
|
||||
|
||||
l = atoi(length);
|
||||
|
||||
printf("line: %3lu offset: %3lu class: %d type: %d "
|
||||
"tag: %3d length: %3d %s\n",
|
||||
line, (unsigned long)offset, c, ty, ta, l,
|
||||
data ? "<have data>" : "<no data>");
|
||||
|
||||
ret = der_put_length_and_tag(p + sizeof(p) - 1, sizeof(p),
|
||||
l,
|
||||
c,
|
||||
ty,
|
||||
ta,
|
||||
&sz);
|
||||
if (ret)
|
||||
errx(1, "der_put_length_and_tag: %d", ret);
|
||||
|
||||
if (fwrite(p + sizeof(p) - sz , sz, 1, fout) != 1)
|
||||
err(1, "fwrite length/tag failed");
|
||||
offset += sz;
|
||||
|
||||
if (data) {
|
||||
size_t datalen;
|
||||
|
||||
datalen = strlen(data) / 2;
|
||||
pdata = emalloc(sz);
|
||||
|
||||
if (hex_decode(data, pdata, datalen) != datalen)
|
||||
errx(1, "failed to decode data");
|
||||
|
||||
if (fwrite(pdata, datalen, 1, fout) != 1)
|
||||
err(1, "fwrite data failed");
|
||||
offset += datalen;
|
||||
|
||||
free(pdata);
|
||||
}
|
||||
}
|
||||
printf("line: eof offset: %lu\n", (unsigned long)offset);
|
||||
|
||||
fclose(fout);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int version_flag;
|
||||
static int help_flag;
|
||||
struct getargs args[] = {
|
||||
{ "version", 0, arg_flag, &version_flag },
|
||||
{ "help", 0, arg_flag, &help_flag }
|
||||
};
|
||||
int num_args = sizeof(args) / sizeof(args[0]);
|
||||
|
||||
static void
|
||||
usage(int code)
|
||||
{
|
||||
arg_printusage(args, num_args, NULL, "parse-file");
|
||||
exit(code);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int optind = 0;
|
||||
|
||||
setprogname (argv[0]);
|
||||
|
||||
if(getarg(args, num_args, argc, argv, &optind))
|
||||
usage(1);
|
||||
if(help_flag)
|
||||
usage(0);
|
||||
if(version_flag) {
|
||||
print_version(NULL);
|
||||
exit(0);
|
||||
}
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
if (argc != 1)
|
||||
usage (1);
|
||||
|
||||
return doit (argv[0]);
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2002 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -37,55 +37,20 @@
|
||||
#include <sys/stat.h>
|
||||
#include <getarg.h>
|
||||
#include <err.h>
|
||||
#include <der.h>
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
const char *class_names[] = {
|
||||
"UNIV", /* 0 */
|
||||
"APPL", /* 1 */
|
||||
"CONTEXT", /* 2 */
|
||||
"PRIVATE" /* 3 */
|
||||
};
|
||||
static int indent_flag = 1;
|
||||
|
||||
const char *type_names[] = {
|
||||
"PRIM", /* 0 */
|
||||
"CONS" /* 1 */
|
||||
};
|
||||
static unsigned long indefinite_form_loop;
|
||||
static unsigned long indefinite_form_loop_max = 10000;
|
||||
|
||||
const char *tag_names[] = {
|
||||
NULL, /* 0 */
|
||||
NULL, /* 1 */
|
||||
"Integer", /* 2 */
|
||||
"BitString", /* 3 */
|
||||
"OctetString", /* 4 */
|
||||
"Null", /* 5 */
|
||||
"ObjectID", /* 6 */
|
||||
NULL, /* 7 */
|
||||
NULL, /* 8 */
|
||||
NULL, /* 9 */
|
||||
"Enumerated", /* 10 */
|
||||
NULL, /* 11 */
|
||||
NULL, /* 12 */
|
||||
NULL, /* 13 */
|
||||
NULL, /* 14 */
|
||||
NULL, /* 15 */
|
||||
"Sequence", /* 16 */
|
||||
"Set", /* 17 */
|
||||
NULL, /* 18 */
|
||||
"PrintableString", /* 19 */
|
||||
NULL, /* 20 */
|
||||
NULL, /* 21 */
|
||||
"IA5String", /* 22 */
|
||||
"UTCTime", /* 23 */
|
||||
"GeneralizedTime", /* 24 */
|
||||
NULL, /* 25 */
|
||||
"VisibleString", /* 26 */
|
||||
"GeneralString" /* 27 */
|
||||
};
|
||||
|
||||
static int
|
||||
static size_t
|
||||
loop (unsigned char *buf, size_t len, int indent)
|
||||
{
|
||||
unsigned char *start_buf = buf;
|
||||
|
||||
while (len > 0) {
|
||||
int ret;
|
||||
Der_class class;
|
||||
@@ -93,7 +58,9 @@ loop (unsigned char *buf, size_t len, int indent)
|
||||
int tag;
|
||||
size_t sz;
|
||||
size_t length;
|
||||
int i;
|
||||
size_t loop_length = 0;
|
||||
int end_tag = 0;
|
||||
const char *tagname;
|
||||
|
||||
ret = der_get_tag (buf, len, &class, &type, &tag, &sz);
|
||||
if (ret)
|
||||
@@ -103,62 +70,99 @@ loop (unsigned char *buf, size_t len, int indent)
|
||||
(unsigned)sz, (unsigned)len);
|
||||
buf += sz;
|
||||
len -= sz;
|
||||
for (i = 0; i < indent; ++i)
|
||||
printf (" ");
|
||||
printf ("%s %s ", class_names[class], type_names[type]);
|
||||
if (tag_names[tag])
|
||||
printf ("%s = ", tag_names[tag]);
|
||||
if (indent_flag) {
|
||||
int i;
|
||||
for (i = 0; i < indent; ++i)
|
||||
printf (" ");
|
||||
}
|
||||
printf ("%s %s ", der_get_class_name(class), der_get_type_name(type));
|
||||
tagname = der_get_tag_name(tag);
|
||||
if (class == ASN1_C_UNIV && tagname != NULL)
|
||||
printf ("%s = ", tagname);
|
||||
else
|
||||
printf ("tag %d = ", tag);
|
||||
ret = der_get_length (buf, len, &length, &sz);
|
||||
if (ret)
|
||||
errx (1, "der_get_tag: %s", error_message (ret));
|
||||
if (sz > len)
|
||||
errx (1, "unreasonable tag length (%u) > %u",
|
||||
(unsigned)sz, (unsigned)len);
|
||||
buf += sz;
|
||||
len -= sz;
|
||||
|
||||
if (class == ASN1_C_CONTEXT) {
|
||||
printf ("[%d]\n", tag);
|
||||
loop (buf, length, indent);
|
||||
if (length == ASN1_INDEFINITE) {
|
||||
if ((class == ASN1_C_UNIV && type == PRIM && tag == UT_OctetString) ||
|
||||
(class == ASN1_C_CONTEXT && type == CONS) ||
|
||||
(class == ASN1_C_UNIV && type == CONS && tag == UT_Sequence) ||
|
||||
(class == ASN1_C_UNIV && type == CONS && tag == UT_Set)) {
|
||||
printf("*INDEFINITE FORM*");
|
||||
} else {
|
||||
fflush(stdout);
|
||||
errx(1, "indef form used on unsupported object");
|
||||
}
|
||||
end_tag = 1;
|
||||
if (indefinite_form_loop > indefinite_form_loop_max)
|
||||
errx(1, "indefinite form used recursively more then %lu "
|
||||
"times, aborting", indefinite_form_loop_max);
|
||||
indefinite_form_loop++;
|
||||
length = len;
|
||||
} else if (length > len) {
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
errx (1, "unreasonable inner length (%u) > %u",
|
||||
(unsigned)length, (unsigned)len);
|
||||
}
|
||||
if (class == ASN1_C_CONTEXT || class == ASN1_C_APPL) {
|
||||
printf ("%d bytes [%d]\n", length, tag);
|
||||
if (type == CONS)
|
||||
loop_length = loop (buf, length, indent + 2);
|
||||
} else if (class == ASN1_C_UNIV) {
|
||||
switch (tag) {
|
||||
case UT_EndOfContent:
|
||||
printf (" INDEFINITE length was %lu\n",
|
||||
(unsigned long)(buf - start_buf));
|
||||
break;
|
||||
case UT_Set :
|
||||
case UT_Sequence :
|
||||
printf ("{\n");
|
||||
loop (buf, length, indent + 2);
|
||||
for (i = 0; i < indent; ++i)
|
||||
printf (" ");
|
||||
printf ("}\n");
|
||||
printf ("%lu bytes {\n", (unsigned long)length);
|
||||
loop_length = loop (buf, length, indent + 2);
|
||||
if (indent_flag) {
|
||||
int i;
|
||||
for (i = 0; i < indent; ++i)
|
||||
printf (" ");
|
||||
printf ("}\n");
|
||||
} else
|
||||
printf ("} indent = %d\n", indent / 2);
|
||||
break;
|
||||
case UT_Integer : {
|
||||
int val;
|
||||
|
||||
ret = der_get_int (buf, length, &val, NULL);
|
||||
if (ret)
|
||||
errx (1, "der_get_int: %s", error_message (ret));
|
||||
printf ("integer %d\n", val);
|
||||
if (length <= sizeof(val)) {
|
||||
ret = der_get_integer (buf, length, &val, NULL);
|
||||
if (ret)
|
||||
errx (1, "der_get_integer: %s", error_message (ret));
|
||||
printf ("integer %d\n", val);
|
||||
} else {
|
||||
printf ("BIG NUM integer: length %d\n", length);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UT_OctetString : {
|
||||
heim_octet_string str;
|
||||
int i;
|
||||
unsigned char *uc;
|
||||
|
||||
ret = der_get_octet_string (buf, length, &str, NULL);
|
||||
if (ret)
|
||||
errx (1, "der_get_octet_string: %s", error_message (ret));
|
||||
printf ("(length %lu)%s", (unsigned long)str.length,
|
||||
str.length > 0 ? ", " : "");
|
||||
printf ("(length %lu), ", (unsigned long)length);
|
||||
uc = (unsigned char *)str.data;
|
||||
length = str.length;
|
||||
if (length > 16)
|
||||
length = 16;
|
||||
for (i = 0; i < length; ++i)
|
||||
for (i = 0; i < min(16,length); ++i)
|
||||
printf ("%02x", uc[i]);
|
||||
printf ("\n");
|
||||
free (str.data);
|
||||
break;
|
||||
}
|
||||
case UT_GeneralizedTime :
|
||||
case UT_IA5String:
|
||||
case UT_UTF8String :
|
||||
case UT_GeneralString : {
|
||||
heim_general_string str;
|
||||
|
||||
@@ -172,6 +176,7 @@ loop (unsigned char *buf, size_t len, int indent)
|
||||
}
|
||||
case UT_OID: {
|
||||
heim_oid o;
|
||||
int i;
|
||||
|
||||
ret = der_get_oid(buf, length, &o, NULL);
|
||||
if (ret)
|
||||
@@ -185,9 +190,9 @@ loop (unsigned char *buf, size_t len, int indent)
|
||||
break;
|
||||
}
|
||||
case UT_Enumerated: {
|
||||
unsigned num;
|
||||
int num;
|
||||
|
||||
ret = der_get_int (buf, length, &num, NULL);
|
||||
ret = der_get_integer (buf, length, &num, NULL);
|
||||
if (ret)
|
||||
errx (1, "der_get_enum: %s", error_message (ret));
|
||||
|
||||
@@ -199,6 +204,17 @@ loop (unsigned char *buf, size_t len, int indent)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (end_tag) {
|
||||
if (loop_length == 0)
|
||||
errx(1, "zero length INDEFINITE data ? indent = %d\n",
|
||||
indent / 2);
|
||||
if (loop_length < length)
|
||||
length = loop_length;
|
||||
if (indefinite_form_loop == 0)
|
||||
errx(1, "internal error in indefinite form loop detection");
|
||||
indefinite_form_loop--;
|
||||
} else if (loop_length)
|
||||
errx(1, "internal error for INDEFINITE form");
|
||||
buf += length;
|
||||
len -= length;
|
||||
}
|
||||
@@ -219,21 +235,20 @@ doit (const char *filename)
|
||||
if (fstat (fd, &sb) < 0)
|
||||
err (1, "stat %s", filename);
|
||||
len = sb.st_size;
|
||||
buf = malloc (len);
|
||||
if (buf == NULL)
|
||||
err (1, "malloc %u", (unsigned)len);
|
||||
buf = emalloc (len);
|
||||
if (read (fd, buf, len) != len)
|
||||
errx (1, "read failed");
|
||||
close (fd);
|
||||
ret = loop (buf, len, 0);
|
||||
free (buf);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int version_flag;
|
||||
static int help_flag;
|
||||
struct getargs args[] = {
|
||||
{ "indent", 0, arg_negative_flag, &indent_flag },
|
||||
{ "version", 0, arg_flag, &version_flag },
|
||||
{ "help", 0, arg_flag, &help_flag }
|
||||
};
|
||||
@@ -249,11 +264,11 @@ usage(int code)
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int optidx = 0;
|
||||
int optind = 0;
|
||||
|
||||
setprogname (argv[0]);
|
||||
initialize_asn1_error_table ();
|
||||
if(getarg(args, num_args, argc, argv, &optidx))
|
||||
if(getarg(args, num_args, argc, argv, &optind))
|
||||
usage(1);
|
||||
if(help_flag)
|
||||
usage(0);
|
||||
@@ -261,8 +276,8 @@ main(int argc, char **argv)
|
||||
print_version(NULL);
|
||||
exit(0);
|
||||
}
|
||||
argv += optidx;
|
||||
argc -= optidx;
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
if (argc != 1)
|
||||
usage (1);
|
||||
return doit (argv[0]);
|
||||
|
167
lib/asn1/asn1_queue.h
Normal file
167
lib/asn1/asn1_queue.h
Normal file
@@ -0,0 +1,167 @@
|
||||
/* $NetBSD: queue.h,v 1.38 2004/04/18 14:12:05 lukem Exp $ */
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
||||
*/
|
||||
|
||||
#ifndef _ASN1_QUEUE_H_
|
||||
#define _ASN1_QUEUE_H_
|
||||
|
||||
/*
|
||||
* Tail queue definitions.
|
||||
*/
|
||||
#define ASN1_TAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *tqh_first; /* first element */ \
|
||||
struct type **tqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define ASN1_TAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).tqh_first }
|
||||
#define ASN1_TAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *tqe_next; /* next element */ \
|
||||
struct type **tqe_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Tail queue functions.
|
||||
*/
|
||||
#if defined(_KERNEL) && defined(QUEUEDEBUG)
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_INSERT_HEAD(head, elm, field) \
|
||||
if ((head)->tqh_first && \
|
||||
(head)->tqh_first->field.tqe_prev != &(head)->tqh_first) \
|
||||
panic("ASN1_TAILQ_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_INSERT_TAIL(head, elm, field) \
|
||||
if (*(head)->tqh_last != NULL) \
|
||||
panic("ASN1_TAILQ_INSERT_TAIL %p %s:%d", (head), __FILE__, __LINE__);
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_OP(elm, field) \
|
||||
if ((elm)->field.tqe_next && \
|
||||
(elm)->field.tqe_next->field.tqe_prev != \
|
||||
&(elm)->field.tqe_next) \
|
||||
panic("ASN1_TAILQ_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
|
||||
if (*(elm)->field.tqe_prev != (elm)) \
|
||||
panic("ASN1_TAILQ_* back %p %s:%d", (elm), __FILE__, __LINE__);
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_PREREMOVE(head, elm, field) \
|
||||
if ((elm)->field.tqe_next == NULL && \
|
||||
(head)->tqh_last != &(elm)->field.tqe_next) \
|
||||
panic("ASN1_TAILQ_PREREMOVE head %p elm %p %s:%d", \
|
||||
(head), (elm), __FILE__, __LINE__);
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_POSTREMOVE(elm, field) \
|
||||
(elm)->field.tqe_next = (void *)1L; \
|
||||
(elm)->field.tqe_prev = (void *)1L;
|
||||
#else
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_INSERT_HEAD(head, elm, field)
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_INSERT_TAIL(head, elm, field)
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_OP(elm, field)
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_PREREMOVE(head, elm, field)
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_POSTREMOVE(elm, field)
|
||||
#endif
|
||||
|
||||
#define ASN1_TAILQ_INIT(head) do { \
|
||||
(head)->tqh_first = NULL; \
|
||||
(head)->tqh_last = &(head)->tqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define ASN1_TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
QUEUEDEBUG_ASN1_TAILQ_INSERT_HEAD((head), (elm), field) \
|
||||
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
|
||||
(head)->tqh_first->field.tqe_prev = \
|
||||
&(elm)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(head)->tqh_first = (elm); \
|
||||
(elm)->field.tqe_prev = &(head)->tqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define ASN1_TAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
QUEUEDEBUG_ASN1_TAILQ_INSERT_TAIL((head), (elm), field) \
|
||||
(elm)->field.tqe_next = NULL; \
|
||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||
*(head)->tqh_last = (elm); \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define ASN1_TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
QUEUEDEBUG_ASN1_TAILQ_OP((listelm), field) \
|
||||
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
&(elm)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(listelm)->field.tqe_next = (elm); \
|
||||
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define ASN1_TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
QUEUEDEBUG_ASN1_TAILQ_OP((listelm), field) \
|
||||
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||
(elm)->field.tqe_next = (listelm); \
|
||||
*(listelm)->field.tqe_prev = (elm); \
|
||||
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define ASN1_TAILQ_REMOVE(head, elm, field) do { \
|
||||
QUEUEDEBUG_ASN1_TAILQ_PREREMOVE((head), (elm), field) \
|
||||
QUEUEDEBUG_ASN1_TAILQ_OP((elm), field) \
|
||||
if (((elm)->field.tqe_next) != NULL) \
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
(elm)->field.tqe_prev; \
|
||||
else \
|
||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
|
||||
QUEUEDEBUG_ASN1_TAILQ_POSTREMOVE((elm), field); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define ASN1_TAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->tqh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.tqe_next))
|
||||
|
||||
#define ASN1_TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||
for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
|
||||
(var); \
|
||||
(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
|
||||
|
||||
/*
|
||||
* Tail queue access methods.
|
||||
*/
|
||||
#define ASN1_TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||
#define ASN1_TAILQ_FIRST(head) ((head)->tqh_first)
|
||||
#define ASN1_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
|
||||
#define ASN1_TAILQ_LAST(head, headname) \
|
||||
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||
#define ASN1_TAILQ_PREV(elm, headname, field) \
|
||||
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||
|
||||
|
||||
#endif /* !_ASN1_QUEUE_H_ */
|
30
lib/asn1/canthandle.asn1
Normal file
30
lib/asn1/canthandle.asn1
Normal file
@@ -0,0 +1,30 @@
|
||||
-- $Id$ --
|
||||
|
||||
CANTHANDLE DEFINITIONS ::= BEGIN
|
||||
|
||||
-- Don't code the tag [0] as a constructed tag for foo.kaka1,
|
||||
-- it should be PRIM (and no type field)
|
||||
-- Workaround is to use heim_any and decode type
|
||||
|
||||
Kaka ::= SEQUENCE {
|
||||
kaka3 [0] INTEGER
|
||||
}
|
||||
|
||||
Foo ::= SEQUENCE {
|
||||
kaka1 [0] IMPLICIT INTEGER OPTIONAL,
|
||||
kaka2 [1] IMPLICIT Kaka OPTIONAL
|
||||
}
|
||||
|
||||
-- Don't code kaka if its 1
|
||||
-- Workaround is to use OPTIONAL and check for in the encoder stubs
|
||||
|
||||
Bar ::= SEQUENCE {
|
||||
kaka [0] INTEGER DEFAULT 1
|
||||
}
|
||||
|
||||
-- Can't handle primitives in SET OF
|
||||
-- Workaround is to define a type that is only an integer and use that
|
||||
|
||||
Baz ::= SET OF INTEGER
|
||||
|
||||
END
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999 - 2003 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1999 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -34,6 +34,9 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
@@ -43,6 +46,107 @@
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
struct map_page {
|
||||
void *start;
|
||||
size_t size;
|
||||
void *data_start;
|
||||
size_t data_size;
|
||||
enum map_type type;
|
||||
};
|
||||
|
||||
/* #undef HAVE_MMAP */
|
||||
|
||||
void *
|
||||
map_alloc(enum map_type type, const void *buf,
|
||||
size_t size, struct map_page **map)
|
||||
{
|
||||
#ifndef HAVE_MMAP
|
||||
unsigned char *p;
|
||||
|
||||
*map = ecalloc(1, sizeof(**map));
|
||||
|
||||
p = emalloc(size + 2);
|
||||
(*map)->type = type;
|
||||
(*map)->start = p;
|
||||
(*map)->size = size + 2;
|
||||
p[0] = 0xff;
|
||||
p[(*map)->size] = 0xff;
|
||||
(*map)->data_start = p + 1;
|
||||
#else
|
||||
unsigned char *p;
|
||||
int flags, ret, fd;
|
||||
size_t pagesize = getpagesize();
|
||||
|
||||
*map = ecalloc(1, sizeof(**map));
|
||||
|
||||
(*map)->type = type;
|
||||
|
||||
#ifdef MAP_ANON
|
||||
flags = MAP_ANON;
|
||||
fd = -1;
|
||||
#else
|
||||
flags = 0;
|
||||
fd = open ("/dev/zero", O_RDONLY);
|
||||
if(fd < 0)
|
||||
err (1, "open /dev/zero");
|
||||
#endif
|
||||
flags |= MAP_PRIVATE;
|
||||
|
||||
(*map)->size = size + pagesize - (size % pagesize) + pagesize * 2;
|
||||
|
||||
p = (char *)mmap(0, (*map)->size, PROT_READ | PROT_WRITE,
|
||||
flags, fd, 0);
|
||||
if (p == (unsigned char *)MAP_FAILED)
|
||||
err (1, "mmap");
|
||||
|
||||
(*map)->start = p;
|
||||
|
||||
ret = mprotect (p, pagesize, 0);
|
||||
if (ret < 0)
|
||||
err (1, "mprotect");
|
||||
|
||||
ret = mprotect (p + (*map)->size - pagesize, pagesize, 0);
|
||||
if (ret < 0)
|
||||
err (1, "mprotect");
|
||||
|
||||
switch (type) {
|
||||
case OVERRUN:
|
||||
(*map)->data_start = p + (*map)->size - pagesize - size;
|
||||
break;
|
||||
case UNDERRUN:
|
||||
(*map)->data_start = p + pagesize;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
(*map)->data_size = size;
|
||||
if (buf)
|
||||
memcpy((*map)->data_start, buf, size);
|
||||
return (*map)->data_start;
|
||||
}
|
||||
|
||||
void
|
||||
map_free(struct map_page *map, const char *test_name, const char *map_name)
|
||||
{
|
||||
#ifndef HAVE_MMAP
|
||||
unsigned char *p = map->start;
|
||||
|
||||
if (p[0] != 0xff)
|
||||
errx(1, "%s: %s underrun %x\n", test_name, map_name, p[0]);
|
||||
if (p[map->size] != 0xff)
|
||||
errx(1, "%s: %s overrun %x\n", test_name, map_name, p[map->size - 1]);
|
||||
free(map->start);
|
||||
#else
|
||||
int ret;
|
||||
|
||||
ret = munmap (map->start, map->size);
|
||||
if (ret < 0)
|
||||
err (1, "munmap");
|
||||
#endif
|
||||
free(map);
|
||||
}
|
||||
|
||||
static void
|
||||
print_bytes (unsigned const char *buf, size_t len)
|
||||
{
|
||||
@@ -52,6 +156,31 @@ print_bytes (unsigned const char *buf, size_t len)
|
||||
printf ("%02x ", buf[i]);
|
||||
}
|
||||
|
||||
#ifndef MAP_FAILED
|
||||
#define MAP_FAILED (-1)
|
||||
#endif
|
||||
|
||||
static char *current_test = "<uninit>";
|
||||
static char *current_state = "<uninit>";
|
||||
|
||||
static RETSIGTYPE
|
||||
segv_handler(int sig)
|
||||
{
|
||||
int fd;
|
||||
char msg[] = "SIGSEGV i current test: ";
|
||||
|
||||
fd = open("/dev/stdout", O_WRONLY, 0600);
|
||||
if (fd >= 0) {
|
||||
write(fd, msg, sizeof(msg));
|
||||
write(fd, current_test, strlen(current_test));
|
||||
write(fd, " ", 1);
|
||||
write(fd, current_state, strlen(current_state));
|
||||
write(fd, "\n", 1);
|
||||
close(fd);
|
||||
}
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
generic_test (const struct test_case *tests,
|
||||
unsigned ntests,
|
||||
@@ -59,67 +188,181 @@ generic_test (const struct test_case *tests,
|
||||
int (*encode)(unsigned char *, size_t, void *, size_t *),
|
||||
int (*length)(void *),
|
||||
int (*decode)(unsigned char *, size_t, void *, size_t *),
|
||||
int (*free_data)(void *),
|
||||
int (*cmp)(void *a, void *b))
|
||||
{
|
||||
unsigned char buf[4711];
|
||||
unsigned char *buf, *buf2;
|
||||
int i;
|
||||
int failures = 0;
|
||||
void *val = malloc (data_size);
|
||||
void *data;
|
||||
struct map_page *data_map, *buf_map, *buf2_map;
|
||||
|
||||
if (data_size != 0 && val == NULL)
|
||||
err (1, "malloc");
|
||||
struct sigaction sa, osa;
|
||||
|
||||
for (i = 0; i < ntests; ++i) {
|
||||
int ret;
|
||||
size_t sz, consumed_sz, length_sz;
|
||||
unsigned char *beg;
|
||||
size_t sz, consumed_sz, length_sz, buf_sz;
|
||||
|
||||
ret = (*encode) (buf + sizeof(buf) - 1, sizeof(buf),
|
||||
current_test = tests[i].name;
|
||||
|
||||
current_state = "init";
|
||||
|
||||
sigemptyset (&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
#ifdef SA_RESETHAND
|
||||
sa.sa_flags |= SA_RESETHAND;
|
||||
#endif
|
||||
sa.sa_handler = segv_handler;
|
||||
sigaction (SIGSEGV, &sa, &osa);
|
||||
|
||||
data = map_alloc(OVERRUN, NULL, data_size, &data_map);
|
||||
|
||||
buf_sz = tests[i].byte_len;
|
||||
buf = map_alloc(UNDERRUN, NULL, buf_sz, &buf_map);
|
||||
|
||||
current_state = "encode";
|
||||
ret = (*encode) (buf + buf_sz - 1, buf_sz,
|
||||
tests[i].val, &sz);
|
||||
beg = buf + sizeof(buf) - sz;
|
||||
if (ret != 0) {
|
||||
printf ("encoding of %s failed\n", tests[i].name);
|
||||
printf ("encoding of %s failed %d\n", tests[i].name, ret);
|
||||
++failures;
|
||||
continue;
|
||||
}
|
||||
if (sz != tests[i].byte_len) {
|
||||
printf ("encoding of %s has wrong len (%lu != %lu)\n",
|
||||
tests[i].name,
|
||||
(unsigned long)sz, (unsigned long)tests[i].byte_len);
|
||||
++failures;
|
||||
continue;
|
||||
}
|
||||
|
||||
current_state = "length";
|
||||
length_sz = (*length) (tests[i].val);
|
||||
if (sz != length_sz) {
|
||||
printf ("length for %s is bad (%lu != %lu)\n",
|
||||
tests[i].name, (unsigned long)length_sz, (unsigned long)sz);
|
||||
++failures;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (memcmp (beg, tests[i].bytes, tests[i].byte_len) != 0) {
|
||||
current_state = "memcmp";
|
||||
if (memcmp (buf, tests[i].bytes, tests[i].byte_len) != 0) {
|
||||
printf ("encoding of %s has bad bytes:\n"
|
||||
"correct: ", tests[i].name);
|
||||
print_bytes (tests[i].bytes, tests[i].byte_len);
|
||||
printf ("\nactual: ");
|
||||
print_bytes (beg, sz);
|
||||
print_bytes (buf, sz);
|
||||
printf ("\n");
|
||||
++failures;
|
||||
continue;
|
||||
}
|
||||
ret = (*decode) (beg, sz, val, &consumed_sz);
|
||||
|
||||
buf2 = map_alloc(OVERRUN, buf, sz, &buf2_map);
|
||||
|
||||
current_state = "decode";
|
||||
ret = (*decode) (buf2, sz, data, &consumed_sz);
|
||||
if (ret != 0) {
|
||||
printf ("decoding of %s failed\n", tests[i].name);
|
||||
printf ("decoding of %s failed %d\n", tests[i].name, ret);
|
||||
++failures;
|
||||
continue;
|
||||
}
|
||||
if (sz != consumed_sz) {
|
||||
printf ("different length decoding %s (%ld != %ld)\n",
|
||||
tests[i].name,
|
||||
(unsigned long)sz, (unsigned long)consumed_sz);
|
||||
++failures;
|
||||
continue;
|
||||
}
|
||||
if ((*cmp)(val, tests[i].val) != 0) {
|
||||
current_state = "cmp";
|
||||
if ((*cmp)(data, tests[i].val) != 0) {
|
||||
printf ("%s: comparison failed\n", tests[i].name);
|
||||
++failures;
|
||||
continue;
|
||||
}
|
||||
current_state = "free";
|
||||
if (free_data)
|
||||
(*free_data)(data);
|
||||
|
||||
current_state = "free";
|
||||
map_free(buf_map, tests[i].name, "encode");
|
||||
map_free(buf2_map, tests[i].name, "decode");
|
||||
map_free(data_map, tests[i].name, "data");
|
||||
|
||||
sigaction (SIGSEGV, &osa, NULL);
|
||||
}
|
||||
free (val);
|
||||
current_state = "done";
|
||||
return failures;
|
||||
}
|
||||
|
||||
/*
|
||||
* check for failures
|
||||
*
|
||||
* a test size (byte_len) of -1 means that the test tries to trigger a
|
||||
* integer overflow (and later a malloc of to little memory), just
|
||||
* allocate some memory and hope that is enough for that test.
|
||||
*/
|
||||
|
||||
int
|
||||
generic_decode_fail (const struct test_case *tests,
|
||||
unsigned ntests,
|
||||
size_t data_size,
|
||||
int (*decode)(unsigned char *, size_t, void *, size_t *))
|
||||
{
|
||||
unsigned char *buf;
|
||||
int i;
|
||||
int failures = 0;
|
||||
void *data;
|
||||
struct map_page *data_map, *buf_map;
|
||||
|
||||
struct sigaction sa, osa;
|
||||
|
||||
for (i = 0; i < ntests; ++i) {
|
||||
int ret;
|
||||
size_t sz;
|
||||
const void *bytes;
|
||||
|
||||
current_test = tests[i].name;
|
||||
|
||||
current_state = "init";
|
||||
|
||||
sigemptyset (&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
#ifdef SA_RESETHAND
|
||||
sa.sa_flags |= SA_RESETHAND;
|
||||
#endif
|
||||
sa.sa_handler = segv_handler;
|
||||
sigaction (SIGSEGV, &sa, &osa);
|
||||
|
||||
data = map_alloc(OVERRUN, NULL, data_size, &data_map);
|
||||
|
||||
if (tests[i].byte_len != -1) {
|
||||
sz = tests[i].byte_len;
|
||||
bytes = tests[i].bytes;
|
||||
} else {
|
||||
sz = 4096;
|
||||
bytes = NULL;
|
||||
}
|
||||
|
||||
buf = map_alloc(OVERRUN, bytes, sz, &buf_map);
|
||||
|
||||
if (tests[i].byte_len == -1)
|
||||
memset(buf, 0, sz);
|
||||
|
||||
current_state = "decode";
|
||||
ret = (*decode) (buf, tests[i].byte_len, data, &sz);
|
||||
if (ret == 0) {
|
||||
printf ("sucessfully decoded %s\n", tests[i].name);
|
||||
++failures;
|
||||
continue;
|
||||
}
|
||||
|
||||
current_state = "free";
|
||||
if (buf)
|
||||
map_free(buf_map, tests[i].name, "encode");
|
||||
map_free(data_map, tests[i].name, "data");
|
||||
|
||||
sigaction (SIGSEGV, &osa, NULL);
|
||||
}
|
||||
current_state = "done";
|
||||
return failures;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999 - 2003 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1999 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -41,6 +41,7 @@ struct test_case {
|
||||
typedef int (*generic_encode)(unsigned char *, size_t, void *, size_t *);
|
||||
typedef int (*generic_length)(void *);
|
||||
typedef int (*generic_decode)(unsigned char *, size_t, void *, size_t *);
|
||||
typedef int (*generic_free)(void *);
|
||||
|
||||
int
|
||||
generic_test (const struct test_case *tests,
|
||||
@@ -49,5 +50,21 @@ generic_test (const struct test_case *tests,
|
||||
int (*encode)(unsigned char *, size_t, void *, size_t *),
|
||||
int (*length)(void *),
|
||||
int (*decode)(unsigned char *, size_t, void *, size_t *),
|
||||
int (*free_data)(void *),
|
||||
int (*cmp)(void *a, void *b));
|
||||
|
||||
int
|
||||
generic_decode_fail(const struct test_case *tests,
|
||||
unsigned ntests,
|
||||
size_t data_size,
|
||||
int (*decode)(unsigned char *, size_t, void *, size_t *));
|
||||
|
||||
|
||||
struct map_page;
|
||||
|
||||
enum map_type { OVERRUN, UNDERRUN };
|
||||
|
||||
struct map_page;
|
||||
|
||||
void * map_alloc(enum map_type, const void *, size_t, struct map_page **);
|
||||
void map_free(struct map_page *, const char *, const char *);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999 - 2003 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1999 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -56,17 +56,17 @@ static int
|
||||
test_integer (void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, 3, "\x02\x01\x00"},
|
||||
{NULL, 3, "\x02\x01\x7f"},
|
||||
{NULL, 4, "\x02\x02\x00\x80"},
|
||||
{NULL, 4, "\x02\x02\x01\x00"},
|
||||
{NULL, 3, "\x02\x01\x80"},
|
||||
{NULL, 4, "\x02\x02\xff\x7f"},
|
||||
{NULL, 3, "\x02\x01\xff"},
|
||||
{NULL, 4, "\x02\x02\xff\x01"},
|
||||
{NULL, 4, "\x02\x02\x00\xff"},
|
||||
{NULL, 6, "\x02\x04\x80\x00\x00\x00"},
|
||||
{NULL, 6, "\x02\x04\x7f\xff\xff\xff"}
|
||||
{NULL, 1, "\x00"},
|
||||
{NULL, 1, "\x7f"},
|
||||
{NULL, 2, "\x00\x80"},
|
||||
{NULL, 2, "\x01\x00"},
|
||||
{NULL, 1, "\x80"},
|
||||
{NULL, 2, "\xff\x7f"},
|
||||
{NULL, 1, "\xff"},
|
||||
{NULL, 2, "\xff\x01"},
|
||||
{NULL, 2, "\x00\xff"},
|
||||
{NULL, 4, "\x80\x00\x00\x00"},
|
||||
{NULL, 4, "\x7f\xff\xff\xff"}
|
||||
};
|
||||
|
||||
int values[] = {0, 127, 128, 256, -128, -129, -1, -255, 255,
|
||||
@@ -77,21 +77,23 @@ test_integer (void)
|
||||
for (i = 0; i < ntests; ++i) {
|
||||
tests[i].val = &values[i];
|
||||
asprintf (&tests[i].name, "integer %d", values[i]);
|
||||
if (tests[i].name == NULL)
|
||||
errx(1, "malloc");
|
||||
}
|
||||
|
||||
return generic_test (tests, ntests, sizeof(int),
|
||||
(generic_encode)encode_integer,
|
||||
(generic_encode)der_put_integer,
|
||||
(generic_length) length_integer,
|
||||
(generic_decode)decode_integer,
|
||||
(generic_decode)der_get_integer,
|
||||
(generic_free)NULL,
|
||||
cmp_integer);
|
||||
}
|
||||
|
||||
static int
|
||||
test_one_int(int val)
|
||||
{
|
||||
int ret, dval;
|
||||
int len, ret, len_len, dval;
|
||||
unsigned char *buf;
|
||||
size_t len_len, len;
|
||||
|
||||
len = _heim_len_int(val);
|
||||
|
||||
@@ -101,25 +103,25 @@ test_one_int(int val)
|
||||
buf[len + 1] = '\xff';
|
||||
memset(buf + 1, 0, len);
|
||||
|
||||
ret = der_put_int(buf + 1 + len - 1, len, val, &len_len);
|
||||
ret = der_put_integer(buf + 1 + len - 1, len, &val, &len_len);
|
||||
if (ret) {
|
||||
printf("integer %d encode failed %d\n", val, ret);
|
||||
return 1;
|
||||
}
|
||||
if (len != len_len) {
|
||||
printf("integer %d encode fail with %d len %lu, result len %lu\n",
|
||||
val, ret, (unsigned long)len, (unsigned long)len_len);
|
||||
printf("integer %d encode fail with %d len %d, result len %d\n",
|
||||
val, ret, len, len_len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = der_get_int(buf + 1, len, &dval, &len_len);
|
||||
ret = der_get_integer(buf + 1, len, &dval, &len_len);
|
||||
if (ret) {
|
||||
printf("integer %d decode failed %d\n", val, ret);
|
||||
return 1;
|
||||
}
|
||||
if (len != len_len) {
|
||||
printf("integer %d decoded diffrent len %lu != %lu",
|
||||
val, (unsigned long)len, (unsigned long)len_len);
|
||||
printf("integer %d decoded diffrent len %d != %d",
|
||||
val, len, len_len);
|
||||
return 1;
|
||||
}
|
||||
if (val != dval) {
|
||||
@@ -174,14 +176,14 @@ static int
|
||||
test_unsigned (void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, 3, "\x02\x01\x00"},
|
||||
{NULL, 3, "\x02\x01\x7f"},
|
||||
{NULL, 4, "\x02\x02\x00\x80"},
|
||||
{NULL, 4, "\x02\x02\x01\x00"},
|
||||
{NULL, 4, "\x02\x02\x02\x00"},
|
||||
{NULL, 5, "\x02\x03\x00\x80\x00"},
|
||||
{NULL, 7, "\x02\x05\x00\x80\x00\x00\x00"},
|
||||
{NULL, 6, "\x02\x04\x7f\xff\xff\xff"}
|
||||
{NULL, 1, "\x00"},
|
||||
{NULL, 1, "\x7f"},
|
||||
{NULL, 2, "\x00\x80"},
|
||||
{NULL, 2, "\x01\x00"},
|
||||
{NULL, 2, "\x02\x00"},
|
||||
{NULL, 3, "\x00\x80\x00"},
|
||||
{NULL, 5, "\x00\x80\x00\x00\x00"},
|
||||
{NULL, 4, "\x7f\xff\xff\xff"}
|
||||
};
|
||||
|
||||
unsigned int values[] = {0, 127, 128, 256, 512, 32768,
|
||||
@@ -192,12 +194,15 @@ test_unsigned (void)
|
||||
for (i = 0; i < ntests; ++i) {
|
||||
tests[i].val = &values[i];
|
||||
asprintf (&tests[i].name, "unsigned %u", values[i]);
|
||||
if (tests[i].name == NULL)
|
||||
errx(1, "malloc");
|
||||
}
|
||||
|
||||
return generic_test (tests, ntests, sizeof(int),
|
||||
(generic_encode)encode_unsigned,
|
||||
(generic_length) length_unsigned,
|
||||
(generic_decode)decode_unsigned,
|
||||
(generic_encode)der_put_unsigned,
|
||||
(generic_length)length_unsigned,
|
||||
(generic_decode)der_get_unsigned,
|
||||
(generic_free)NULL,
|
||||
cmp_unsigned);
|
||||
}
|
||||
|
||||
@@ -219,20 +224,63 @@ test_octet_string (void)
|
||||
heim_octet_string s1 = {8, "\x01\x23\x45\x67\x89\xab\xcd\xef"};
|
||||
|
||||
struct test_case tests[] = {
|
||||
{NULL, 10, "\x04\x08\x01\x23\x45\x67\x89\xab\xcd\xef"}
|
||||
{NULL, 8, "\x01\x23\x45\x67\x89\xab\xcd\xef"}
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
tests[0].val = &s1;
|
||||
asprintf (&tests[0].name, "a octet string");
|
||||
if (tests[0].name == NULL)
|
||||
errx(1, "malloc");
|
||||
|
||||
return generic_test (tests, ntests, sizeof(heim_octet_string),
|
||||
(generic_encode)encode_octet_string,
|
||||
(generic_encode)der_put_octet_string,
|
||||
(generic_length)length_octet_string,
|
||||
(generic_decode)decode_octet_string,
|
||||
(generic_decode)der_get_octet_string,
|
||||
(generic_free)free_octet_string,
|
||||
cmp_octet_string);
|
||||
}
|
||||
|
||||
static int
|
||||
cmp_bmp_string (void *a, void *b)
|
||||
{
|
||||
heim_bmp_string *oa = (heim_bmp_string *)a;
|
||||
heim_bmp_string *ob = (heim_bmp_string *)b;
|
||||
|
||||
return heim_bmp_string_cmp(oa, ob);
|
||||
}
|
||||
|
||||
static int
|
||||
test_bmp_string (void)
|
||||
{
|
||||
uint16_t d1[] = { 32 };
|
||||
heim_bmp_string s1 = { 1, d1 };
|
||||
uint16_t d2[] = { 32, 32 };
|
||||
heim_bmp_string s2 = { 2, d2 };
|
||||
|
||||
struct test_case tests[] = {
|
||||
{NULL, 2, "\x00\x20"},
|
||||
{NULL, 4, "\x00\x20\x00\x20"}
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
tests[0].val = &s1;
|
||||
asprintf (&tests[0].name, "a bmp string");
|
||||
if (tests[0].name == NULL)
|
||||
errx(1, "malloc");
|
||||
tests[1].val = &s2;
|
||||
asprintf (&tests[1].name, "second bmp string");
|
||||
if (tests[1].name == NULL)
|
||||
errx(1, "malloc");
|
||||
|
||||
return generic_test (tests, ntests, sizeof(heim_bmp_string),
|
||||
(generic_encode)der_put_bmp_string,
|
||||
(generic_length)length_bmp_string,
|
||||
(generic_decode)der_get_bmp_string,
|
||||
(generic_free)free_bmp_string,
|
||||
cmp_bmp_string);
|
||||
}
|
||||
|
||||
static int
|
||||
cmp_general_string (void *a, void *b)
|
||||
{
|
||||
@@ -248,17 +296,20 @@ test_general_string (void)
|
||||
unsigned char *s1 = "Test User 1";
|
||||
|
||||
struct test_case tests[] = {
|
||||
{NULL, 13, "\x1b\x0b\x54\x65\x73\x74\x20\x55\x73\x65\x72\x20\x31"}
|
||||
{NULL, 11, "\x54\x65\x73\x74\x20\x55\x73\x65\x72\x20\x31"}
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
tests[0].val = &s1;
|
||||
asprintf (&tests[0].name, "the string \"%s\"", s1);
|
||||
if (tests[0].name == NULL)
|
||||
errx(1, "malloc");
|
||||
|
||||
return generic_test (tests, ntests, sizeof(unsigned char *),
|
||||
(generic_encode)encode_general_string,
|
||||
(generic_encode)der_put_general_string,
|
||||
(generic_length)length_general_string,
|
||||
(generic_decode)decode_general_string,
|
||||
(generic_decode)der_get_general_string,
|
||||
(generic_free)free_general_string,
|
||||
cmp_general_string);
|
||||
}
|
||||
|
||||
@@ -275,8 +326,8 @@ static int
|
||||
test_generalized_time (void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, 17, "\x18\x0f""19700101000000Z"},
|
||||
{NULL, 17, "\x18\x0f""19851106210627Z"}
|
||||
{NULL, 15, "19700101000000Z"},
|
||||
{NULL, 15, "19851106210627Z"}
|
||||
};
|
||||
time_t values[] = {0, 500159187};
|
||||
int i;
|
||||
@@ -285,15 +336,211 @@ test_generalized_time (void)
|
||||
for (i = 0; i < ntests; ++i) {
|
||||
tests[i].val = &values[i];
|
||||
asprintf (&tests[i].name, "time %d", (int)values[i]);
|
||||
if (tests[i].name == NULL)
|
||||
errx(1, "malloc");
|
||||
}
|
||||
|
||||
return generic_test (tests, ntests, sizeof(time_t),
|
||||
(generic_encode)encode_generalized_time,
|
||||
(generic_encode)der_put_generalized_time,
|
||||
(generic_length)length_generalized_time,
|
||||
(generic_decode)decode_generalized_time,
|
||||
(generic_decode)der_get_generalized_time,
|
||||
(generic_free)NULL,
|
||||
cmp_generalized_time);
|
||||
}
|
||||
|
||||
static int
|
||||
test_cmp_oid (void *a, void *b)
|
||||
{
|
||||
return heim_oid_cmp((heim_oid *)a, (heim_oid *)b);
|
||||
}
|
||||
|
||||
static int
|
||||
test_oid (void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, 2, "\x29\x01"},
|
||||
{NULL, 1, "\x29"},
|
||||
{NULL, 2, "\xff\x01"},
|
||||
{NULL, 1, "\xff"}
|
||||
};
|
||||
unsigned oid_comp1[] = { 1, 1, 1 };
|
||||
unsigned oid_comp2[] = { 1, 1 };
|
||||
unsigned oid_comp3[] = { 6, 15, 1 };
|
||||
unsigned oid_comp4[] = { 6, 15 };
|
||||
heim_oid values[] = {
|
||||
{ 3, oid_comp1 },
|
||||
{ 2, oid_comp2 },
|
||||
{ 3, oid_comp3 },
|
||||
{ 2, oid_comp4 }
|
||||
};
|
||||
int i;
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
for (i = 0; i < ntests; ++i) {
|
||||
tests[i].val = &values[i];
|
||||
asprintf (&tests[i].name, "oid %d", i);
|
||||
if (tests[i].name == NULL)
|
||||
errx(1, "malloc");
|
||||
}
|
||||
|
||||
return generic_test (tests, ntests, sizeof(heim_oid),
|
||||
(generic_encode)der_put_oid,
|
||||
(generic_length)length_oid,
|
||||
(generic_decode)der_get_oid,
|
||||
(generic_free)free_oid,
|
||||
test_cmp_oid);
|
||||
}
|
||||
|
||||
static int
|
||||
check_fail_unsigned(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, sizeof(unsigned) + 1,
|
||||
"\x01\x01\x01\x01\x01\x01\x01\x01\x01", "data overrun" }
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
return generic_decode_fail(tests, ntests, sizeof(unsigned),
|
||||
(generic_decode)der_get_unsigned);
|
||||
}
|
||||
|
||||
static int
|
||||
check_fail_integer(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, sizeof(int) + 1,
|
||||
"\x01\x01\x01\x01\x01\x01\x01\x01\x01", "data overrun" }
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
return generic_decode_fail(tests, ntests, sizeof(int),
|
||||
(generic_decode)der_get_integer);
|
||||
}
|
||||
|
||||
static int
|
||||
check_fail_length(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, 0, "", "empty input data"},
|
||||
{NULL, 1, "\x82", "internal length overrun" }
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
return generic_decode_fail(tests, ntests, sizeof(size_t),
|
||||
(generic_decode)der_get_length);
|
||||
}
|
||||
|
||||
static int
|
||||
check_fail_boolean(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, 0, "", "empty input data"}
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
return generic_decode_fail(tests, ntests, sizeof(int),
|
||||
(generic_decode)der_get_boolean);
|
||||
}
|
||||
|
||||
static int
|
||||
check_fail_general_string(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, -1, "", "over sized buffer"}
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
return generic_decode_fail(tests, ntests, sizeof(heim_general_string),
|
||||
(generic_decode)der_get_general_string);
|
||||
}
|
||||
|
||||
static int
|
||||
check_fail_bmp_string(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, 1, "\x00", "odd length bmpstring"},
|
||||
{NULL, -1, "\x00", "over sized data"}
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
return generic_decode_fail(tests, ntests, sizeof(heim_bmp_string),
|
||||
(generic_decode)der_get_bmp_string);
|
||||
}
|
||||
|
||||
static int
|
||||
check_fail_universal_string(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, 1, "\x00", "x & 3 == 1 universal string"},
|
||||
{NULL, 2, "\x00\x00", "x & 3 == 2 universal string"},
|
||||
{NULL, 3, "\x00\x00\x00", "x & 3 == 3 universal string"},
|
||||
{NULL, 5, "\x00\x00\x00\x00\x00", "x & 3 == 1 universal string"},
|
||||
{NULL, 6, "\x00\x00\x00\x00\x00\x00", "x & 3 == 2 universal string"},
|
||||
{NULL, 7, "\x00\x00\x00\x00\x00\x00\x00", "x & 3 == 3 universal string"},
|
||||
{NULL, -1, "\x00", "over sized data"}
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
return generic_decode_fail(tests, ntests, sizeof(heim_universal_string),
|
||||
(generic_decode)der_get_universal_string);
|
||||
}
|
||||
|
||||
static int
|
||||
check_fail_heim_integer(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, -1, "\x00", "over sized data"}
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
return generic_decode_fail(tests, ntests, sizeof(heim_integer),
|
||||
(generic_decode)der_get_heim_integer);
|
||||
}
|
||||
|
||||
static int
|
||||
check_fail_generalized_time(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, 1, "\x00", "no time"},
|
||||
{NULL, -1, "\x00", "over sized data"}
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
return generic_decode_fail(tests, ntests, sizeof(time_t),
|
||||
(generic_decode)der_get_generalized_time);
|
||||
}
|
||||
|
||||
static int
|
||||
check_fail_oid(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, 0, "", "empty input data"},
|
||||
{NULL, 2, "\x00\x80", "last byte continuation" },
|
||||
{NULL, 11, "\x00\x81\x80\x80\x80\x80\x80\x80\x80\x80\x00",
|
||||
"oid element overflow" },
|
||||
{NULL, -1, "", "over sized buffer" }
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
return generic_decode_fail(tests, ntests, sizeof(heim_oid),
|
||||
(generic_decode)der_get_oid);
|
||||
}
|
||||
|
||||
static int
|
||||
check_fail_bitstring(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, 0, "", "empty input data"},
|
||||
{NULL, 1, "\x08", "larger then 8 bits trailer"},
|
||||
{NULL, 1, "\x01", "to few bytes for bits"},
|
||||
{NULL, -1, "", "length to short"}
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
return generic_decode_fail(tests, ntests, sizeof(heim_bit_string),
|
||||
(generic_decode)der_get_bit_string);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@@ -303,8 +550,22 @@ main(int argc, char **argv)
|
||||
ret += test_integer_more();
|
||||
ret += test_unsigned ();
|
||||
ret += test_octet_string ();
|
||||
ret += test_bmp_string ();
|
||||
ret += test_general_string ();
|
||||
ret += test_generalized_time ();
|
||||
ret += test_oid ();
|
||||
ret += check_fail_unsigned();
|
||||
ret += check_fail_integer();
|
||||
ret += check_fail_length();
|
||||
ret += check_fail_boolean();
|
||||
ret += check_fail_general_string();
|
||||
ret += check_fail_bmp_string();
|
||||
ret += check_fail_universal_string();
|
||||
ret += check_fail_heim_integer();
|
||||
ret += check_fail_generalized_time();
|
||||
ret += check_fail_oid();
|
||||
ret += check_fail_bitstring();
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999 - 2004 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1999 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -43,16 +43,26 @@
|
||||
#include <asn1_err.h>
|
||||
#include <der.h>
|
||||
#include <krb5_asn1.h>
|
||||
#include <heim_asn1.h>
|
||||
#include <rfc2459_asn1.h>
|
||||
#include <test_asn1.h>
|
||||
|
||||
#include "check-common.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
static char *lha_princ[] = { "lha" };
|
||||
static char *lha_principal[] = { "lha" };
|
||||
static char *lharoot_princ[] = { "lha", "root" };
|
||||
static char *datan_princ[] = { "host", "nutcracker.e.kth.se" };
|
||||
static char *nada_tgt_principal[] = { "krbtgt", "NADA.KTH.SE" };
|
||||
|
||||
|
||||
#define IF_OPT_COMPARE(ac,bc,e) \
|
||||
if (((ac)->e == NULL && (bc)->e != NULL) || (((ac)->e != NULL && (bc)->e == NULL))) return 1; if ((ab)->e)
|
||||
#define COMPARE_OPT_STRING(ac,bc,e) \
|
||||
do { if (strcmp(*(ac)->e, *(bc)->e) != 0) return 1; } while(0)
|
||||
#define COMPARE_OPT_OCTECT_STRING(ac,bc,e) \
|
||||
do { if ((ac)->e->length != (bc)->e->length || memcmp((ac)->e->data, (bc)->e->data, (ac)->e->length) != 0) return 1; } while(0)
|
||||
#define COMPARE_STRING(ac,bc,e) \
|
||||
do { if (strcmp((ac)->e, (bc)->e) != 0) return 1; } while(0)
|
||||
#define COMPARE_INTEGER(ac,bc,e) \
|
||||
@@ -101,7 +111,7 @@ test_principal (void)
|
||||
|
||||
|
||||
Principal values[] = {
|
||||
{ { KRB5_NT_PRINCIPAL, { 1, lha_princ } }, "SU.SE" },
|
||||
{ { KRB5_NT_PRINCIPAL, { 1, lha_principal } }, "SU.SE" },
|
||||
{ { KRB5_NT_PRINCIPAL, { 2, lharoot_princ } }, "SU.SE" },
|
||||
{ { KRB5_NT_SRV_HST, { 2, datan_princ } }, "E.KTH.SE" }
|
||||
};
|
||||
@@ -117,6 +127,7 @@ test_principal (void)
|
||||
(generic_encode)encode_Principal,
|
||||
(generic_length)length_Principal,
|
||||
(generic_decode)decode_Principal,
|
||||
(generic_free)free_Principal,
|
||||
cmp_principal);
|
||||
}
|
||||
|
||||
@@ -161,7 +172,7 @@ test_authenticator (void)
|
||||
};
|
||||
|
||||
Authenticator values[] = {
|
||||
{ 5, "E.KTH.SE", { KRB5_NT_PRINCIPAL, { 1, lha_princ } },
|
||||
{ 5, "E.KTH.SE", { KRB5_NT_PRINCIPAL, { 1, lha_principal } },
|
||||
NULL, 10, 99, NULL, NULL, NULL },
|
||||
{ 5, "SU.SE", { KRB5_NT_PRINCIPAL, { 2, lharoot_princ } },
|
||||
NULL, 292, 999, NULL, NULL, NULL }
|
||||
@@ -178,111 +189,496 @@ test_authenticator (void)
|
||||
(generic_encode)encode_Authenticator,
|
||||
(generic_length)length_Authenticator,
|
||||
(generic_decode)decode_Authenticator,
|
||||
(generic_free)free_Authenticator,
|
||||
cmp_authenticator);
|
||||
}
|
||||
|
||||
static int
|
||||
cmp_AuthorizationData (void *a, void *b)
|
||||
cmp_KRB_ERROR (void *a, void *b)
|
||||
{
|
||||
AuthorizationData *aa = a;
|
||||
AuthorizationData *ab = b;
|
||||
KRB_ERROR *aa = a;
|
||||
KRB_ERROR *ab = b;
|
||||
int i;
|
||||
|
||||
COMPARE_INTEGER(aa,ab,len);
|
||||
COMPARE_INTEGER(aa,ab,pvno);
|
||||
COMPARE_INTEGER(aa,ab,msg_type);
|
||||
|
||||
IF_OPT_COMPARE(aa,ab,ctime) {
|
||||
COMPARE_INTEGER(aa,ab,ctime);
|
||||
}
|
||||
IF_OPT_COMPARE(aa,ab,cusec) {
|
||||
COMPARE_INTEGER(aa,ab,cusec);
|
||||
}
|
||||
COMPARE_INTEGER(aa,ab,stime);
|
||||
COMPARE_INTEGER(aa,ab,susec);
|
||||
COMPARE_INTEGER(aa,ab,error_code);
|
||||
|
||||
IF_OPT_COMPARE(aa,ab,crealm) {
|
||||
COMPARE_OPT_STRING(aa,ab,crealm);
|
||||
}
|
||||
#if 0
|
||||
IF_OPT_COMPARE(aa,ab,cname) {
|
||||
COMPARE_OPT_STRING(aa,ab,cname);
|
||||
}
|
||||
#endif
|
||||
COMPARE_STRING(aa,ab,realm);
|
||||
|
||||
COMPARE_INTEGER(aa,ab,sname.name_string.len);
|
||||
for (i = 0; i < aa->sname.name_string.len; i++)
|
||||
COMPARE_STRING(aa,ab,sname.name_string.val[i]);
|
||||
|
||||
IF_OPT_COMPARE(aa,ab,e_text) {
|
||||
COMPARE_OPT_STRING(aa,ab,e_text);
|
||||
}
|
||||
IF_OPT_COMPARE(aa,ab,e_data) {
|
||||
// COMPARE_OPT_OCTECT_STRING(aa,ab,e_data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char static_buf512[512];
|
||||
|
||||
static int
|
||||
test_AuthorizationData (void)
|
||||
test_krb_error (void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{ NULL, 14,
|
||||
{ NULL, 127,
|
||||
(unsigned char*)
|
||||
"\x30\x0c\x30\x0a\xa0\x03\x02\x01\x01\xa1\x03\x04\x01\x00"
|
||||
"\x7e\x7d\x30\x7b\xa0\x03\x02\x01\x05\xa1\x03\x02\x01\x1e\xa4\x11"
|
||||
"\x18\x0f\x32\x30\x30\x33\x31\x31\x32\x34\x30\x30\x31\x31\x31\x39"
|
||||
"\x5a\xa5\x05\x02\x03\x04\xed\xa5\xa6\x03\x02\x01\x1f\xa7\x0d\x1b"
|
||||
"\x0b\x4e\x41\x44\x41\x2e\x4b\x54\x48\x2e\x53\x45\xa8\x10\x30\x0e"
|
||||
"\xa0\x03\x02\x01\x01\xa1\x07\x30\x05\x1b\x03\x6c\x68\x61\xa9\x0d"
|
||||
"\x1b\x0b\x4e\x41\x44\x41\x2e\x4b\x54\x48\x2e\x53\x45\xaa\x20\x30"
|
||||
"\x1e\xa0\x03\x02\x01\x01\xa1\x17\x30\x15\x1b\x06\x6b\x72\x62\x74"
|
||||
"\x67\x74\x1b\x0b\x4e\x41\x44\x41\x2e\x4b\x54\x48\x2e\x53\x45",
|
||||
"KRB-ERROR Test 1"
|
||||
}
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
KRB_ERROR e1;
|
||||
PrincipalName lhaprincipalname = { 1, { 1, lha_principal } };
|
||||
PrincipalName tgtprincipalname = { 1, { 2, nada_tgt_principal } };
|
||||
char *realm = "NADA.KTH.SE";
|
||||
|
||||
e1.pvno = 5;
|
||||
e1.msg_type = 30;
|
||||
e1.ctime = NULL;
|
||||
e1.cusec = NULL;
|
||||
e1.stime = 1069632679;
|
||||
e1.susec = 322981;
|
||||
e1.error_code = 31;
|
||||
e1.crealm = &realm;
|
||||
e1.cname = &lhaprincipalname;
|
||||
e1.realm = "NADA.KTH.SE";
|
||||
e1.sname = tgtprincipalname;
|
||||
e1.e_text = NULL;
|
||||
e1.e_data = NULL;
|
||||
|
||||
tests[0].val = &e1;
|
||||
|
||||
return generic_test (tests, ntests, sizeof(KRB_ERROR),
|
||||
(generic_encode)encode_KRB_ERROR,
|
||||
(generic_length)length_KRB_ERROR,
|
||||
(generic_decode)decode_KRB_ERROR,
|
||||
(generic_free)free_KRB_ERROR,
|
||||
cmp_KRB_ERROR);
|
||||
}
|
||||
|
||||
static int
|
||||
cmp_Name (void *a, void *b)
|
||||
{
|
||||
/* XXX */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_Name (void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{ NULL, 35,
|
||||
(unsigned char*)
|
||||
"\x30\x21\x31\x1f\x30\x0b\x06\x03\x55\x04\x03\x13\x04\x4c\x6f\x76"
|
||||
"\x65\x30\x10\x06\x03\x55\x04\x07\x13\x09\x53\x54\x4f\x43\x4b\x48"
|
||||
"\x4f\x4c\x4d",
|
||||
"Name CN=Love+L=STOCKHOLM"
|
||||
},
|
||||
{ NULL, 142,
|
||||
{ NULL, 35,
|
||||
(unsigned char*)
|
||||
"\x30\x81\x8b\x30\x81\x88\xa0\x03\x02\x01\x01\xa1\x81\x80\x04\x7e"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
},
|
||||
{ NULL, 132,
|
||||
(unsigned char*)
|
||||
"\x30\x81\x81\x30\x73\xa0\x03\x02\x01\x01\xa1\x6c\x04\x6a\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x30\x0a\xa0\x03\x02\x01\x01\xa1"
|
||||
"\x03\x04\x01\x00"
|
||||
},
|
||||
{ NULL, 134,
|
||||
(unsigned char*)
|
||||
"\x30\x81\x83\x30\x74\xa0\x03\x02\x01\x01\xa1\x6d\x04\x6b\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x0b\xa0\x03\x02\x01\x01"
|
||||
"\xa1\x04\x04\x02\x00\x00"
|
||||
"\x30\x21\x31\x1f\x30\x0b\x06\x03\x55\x04\x03\x13\x04\x4c\x6f\x76"
|
||||
"\x65\x30\x10\x06\x03\x55\x04\x07\x13\x09\x53\x54\x4f\x43\x4b\x48"
|
||||
"\x4f\x4c\x4d",
|
||||
"Name L=STOCKHOLM+CN=Love"
|
||||
}
|
||||
};
|
||||
|
||||
AuthorizationData values[] = {
|
||||
{ 1, NULL },
|
||||
{ 1, NULL },
|
||||
{ 2, NULL },
|
||||
{ 2, NULL }
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
Name n1, n2;
|
||||
RelativeDistinguishedName rdn1[1];
|
||||
RelativeDistinguishedName rdn2[1];
|
||||
AttributeTypeAndValue atv1[2];
|
||||
AttributeTypeAndValue atv2[2];
|
||||
unsigned cmp_CN[] = { 2, 5, 4, 3 };
|
||||
unsigned cmp_L[] = { 2, 5, 4, 7 };
|
||||
|
||||
/* n1 */
|
||||
n1.element = choice_Name_rdnSequence;
|
||||
n1.u.rdnSequence.val = rdn1;
|
||||
n1.u.rdnSequence.len = sizeof(rdn1)/sizeof(rdn1[0]);
|
||||
rdn1[0].val = atv1;
|
||||
rdn1[0].len = sizeof(atv1)/sizeof(atv1[0]);
|
||||
|
||||
atv1[0].type.length = sizeof(cmp_CN)/sizeof(cmp_CN[0]);
|
||||
atv1[0].type.components = cmp_CN;
|
||||
atv1[0].value.element = choice_DirectoryString_printableString;
|
||||
atv1[0].value.u.printableString = "Love";
|
||||
|
||||
atv1[1].type.length = sizeof(cmp_L)/sizeof(cmp_L[0]);
|
||||
atv1[1].type.components = cmp_L;
|
||||
atv1[1].value.element = choice_DirectoryString_printableString;
|
||||
atv1[1].value.u.printableString = "STOCKHOLM";
|
||||
|
||||
/* n2 */
|
||||
n2.element = choice_Name_rdnSequence;
|
||||
n2.u.rdnSequence.val = rdn2;
|
||||
n2.u.rdnSequence.len = sizeof(rdn2)/sizeof(rdn2[0]);
|
||||
rdn2[0].val = atv2;
|
||||
rdn2[0].len = sizeof(atv2)/sizeof(atv2[0]);
|
||||
|
||||
atv2[0].type.length = sizeof(cmp_L)/sizeof(cmp_L[0]);
|
||||
atv2[0].type.components = cmp_L;
|
||||
atv2[0].value.element = choice_DirectoryString_printableString;
|
||||
atv2[0].value.u.printableString = "STOCKHOLM";
|
||||
|
||||
atv2[1].type.length = sizeof(cmp_CN)/sizeof(cmp_CN[0]);
|
||||
atv2[1].type.components = cmp_CN;
|
||||
atv2[1].value.element = choice_DirectoryString_printableString;
|
||||
atv2[1].value.u.printableString = "Love";
|
||||
|
||||
/* */
|
||||
tests[0].val = &n1;
|
||||
tests[1].val = &n2;
|
||||
|
||||
return generic_test (tests, ntests, sizeof(Name),
|
||||
(generic_encode)encode_Name,
|
||||
(generic_length)length_Name,
|
||||
(generic_decode)decode_Name,
|
||||
(generic_free)free_Name,
|
||||
cmp_Name);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
static int
|
||||
check_heim_integer(void)
|
||||
{
|
||||
heim_integer h;
|
||||
BIGNUM *bn = BN_new();
|
||||
unsigned char buf[10];
|
||||
unsigned char buf2[10];
|
||||
size_t len = sizeof(buf), size;
|
||||
size_t len2 = sizeof(buf), size2;
|
||||
int i, ret;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memset(buf2, 0, sizeof(buf2));
|
||||
|
||||
i = -123123;
|
||||
|
||||
BN_zero(bn);
|
||||
if (i < 0)
|
||||
BN_sub_word(bn, -i);
|
||||
else
|
||||
BN_add_word(bn, i);
|
||||
|
||||
h.negative = bn->neg;
|
||||
h.length = BN_num_bytes(bn);
|
||||
h.data = emalloc(h.length);
|
||||
BN_bn2bin(bn, h.data);
|
||||
|
||||
printf("length = %d\n", h.length);
|
||||
|
||||
ret = der_put_heim_integer(buf + len - 1, len, &h, &size);
|
||||
if (ret)
|
||||
errx(1, "der_put_heim_integer: %d", ret);
|
||||
|
||||
ret = der_put_integer(buf2 + len - 1, len2, &i, &size2);
|
||||
if (ret)
|
||||
errx(1, "der_put_heim_integer: %d", ret);
|
||||
|
||||
if (size != size2)
|
||||
errx(1, "size %lu != size2 %lu",
|
||||
(unsigned long)size, (unsigned long)size2);
|
||||
|
||||
if (memcmp(buf + len - 1 - size,
|
||||
buf2 + len - 1 - size,
|
||||
size) != 0)
|
||||
errx(1, "data not the same");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
cmp_KeyUsage (void *a, void *b)
|
||||
{
|
||||
KeyUsage *aa = a;
|
||||
KeyUsage *ab = b;
|
||||
|
||||
return KeyUsage2int(*aa) != KeyUsage2int(*ab);
|
||||
}
|
||||
|
||||
static int
|
||||
test_bit_string (void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{ NULL, 4,
|
||||
"\x03\x02\x07\x80",
|
||||
"bitstring 1"
|
||||
}
|
||||
};
|
||||
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
KeyUsage ku1;
|
||||
|
||||
memset(&ku1, 0, sizeof(ku1));
|
||||
ku1.digitalSignature = 1;
|
||||
|
||||
tests[0].val = &ku1;
|
||||
|
||||
return generic_test (tests, ntests, sizeof(KeyUsage),
|
||||
(generic_encode)encode_KeyUsage,
|
||||
(generic_length)length_KeyUsage,
|
||||
(generic_decode)decode_KeyUsage,
|
||||
(generic_free)free_KeyUsage,
|
||||
cmp_KeyUsage);
|
||||
}
|
||||
|
||||
static int
|
||||
cmp_TESTLargeTag (void *a, void *b)
|
||||
{
|
||||
TESTLargeTag *aa = a;
|
||||
TESTLargeTag *ab = b;
|
||||
|
||||
COMPARE_INTEGER(aa,ab,foo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_large_tag (void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{ NULL, 8, "\x30\x06\xbf\x7f\x03\x02\x01\x01", "large tag 1" }
|
||||
};
|
||||
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
TESTLargeTag lt1;
|
||||
|
||||
memset(<1, 0, sizeof(lt1));
|
||||
lt1.foo = 1;
|
||||
|
||||
tests[0].val = <1;
|
||||
|
||||
return generic_test (tests, ntests, sizeof(TESTLargeTag),
|
||||
(generic_encode)encode_TESTLargeTag,
|
||||
(generic_length)length_TESTLargeTag,
|
||||
(generic_decode)decode_TESTLargeTag,
|
||||
(generic_free)free_TESTLargeTag,
|
||||
cmp_TESTLargeTag);
|
||||
}
|
||||
|
||||
struct test_data {
|
||||
int ok;
|
||||
size_t len;
|
||||
size_t expected_len;
|
||||
void *data;
|
||||
};
|
||||
|
||||
static int
|
||||
check_tag_length(void)
|
||||
{
|
||||
struct test_data td[] = {
|
||||
{ 1, 3, 3, "\x02\x01\x00"},
|
||||
{ 1, 3, 3, "\x02\x01\x7f"},
|
||||
{ 1, 4, 4, "\x02\x02\x00\x80"},
|
||||
{ 1, 4, 4, "\x02\x02\x01\x00"},
|
||||
{ 1, 4, 4, "\x02\x02\x02\x00"},
|
||||
{ 0, 3, 0, "\x02\x02\x00"},
|
||||
{ 0, 3, 0, "\x02\x7f\x7f"},
|
||||
{ 0, 4, 0, "\x02\x03\x00\x80"},
|
||||
{ 0, 4, 0, "\x02\x7f\x01\x00"},
|
||||
{ 0, 5, 0, "\x02\xff\x7f\x02\x00"}
|
||||
};
|
||||
size_t sz;
|
||||
krb5uint32 values[] = {0, 127, 128, 256, 512,
|
||||
0, 127, 128, 256, 512 };
|
||||
krb5uint32 u;
|
||||
int i, ret, failed = 0;
|
||||
void *buf;
|
||||
|
||||
for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) {
|
||||
struct map_page *page;
|
||||
|
||||
buf = map_alloc(OVERRUN, td[i].data, td[i].len, &page);
|
||||
|
||||
ret = decode_krb5uint32(buf, td[i].len, &u, &sz);
|
||||
if (ret) {
|
||||
if (td[i].ok) {
|
||||
printf("failed with tag len test %d\n", i);
|
||||
failed = 1;
|
||||
}
|
||||
} else {
|
||||
if (td[i].ok == 0) {
|
||||
printf("failed with success for tag len test %d\n", i);
|
||||
failed = 1;
|
||||
}
|
||||
if (td[i].expected_len != sz) {
|
||||
printf("wrong expected size for tag test %d\n", i);
|
||||
failed = 1;
|
||||
}
|
||||
if (values[i] != u) {
|
||||
printf("wrong value for tag test %d\n", i);
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
map_free(page, "test", "decode");
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
|
||||
static int
|
||||
cmp_TESTChoice (void *a, void *b)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_choice (void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{ NULL, 5, "\xa1\x03\x02\x01\x01", "large choice 1" },
|
||||
{ NULL, 5, "\xa2\x03\x02\x01\x02", "large choice 2" }
|
||||
};
|
||||
|
||||
int ret = 0, ntests = sizeof(tests) / sizeof(*tests);
|
||||
TESTChoice1 c1;
|
||||
TESTChoice1 c2_1;
|
||||
TESTChoice2 c2_2;
|
||||
|
||||
memset(&c1, 0, sizeof(c1));
|
||||
c1.element = choice_TESTChoice1_i1;
|
||||
c1.u.i1 = 1;
|
||||
tests[0].val = &c1;
|
||||
|
||||
memset(&c2_1, 0, sizeof(c2_1));
|
||||
c2_1.element = choice_TESTChoice1_i2;
|
||||
c2_1.u.i2 = 2;
|
||||
tests[1].val = &c2_1;
|
||||
|
||||
ret += generic_test (tests, ntests, sizeof(TESTChoice1),
|
||||
(generic_encode)encode_TESTChoice1,
|
||||
(generic_length)length_TESTChoice1,
|
||||
(generic_decode)decode_TESTChoice1,
|
||||
(generic_free)free_TESTChoice1,
|
||||
cmp_TESTChoice);
|
||||
|
||||
memset(&c2_2, 0, sizeof(c2_2));
|
||||
c2_2.element = choice_TESTChoice2_asn1_ellipsis;
|
||||
c2_2.u.asn1_ellipsis.data = "\xa2\x03\x02\x01\x02";
|
||||
c2_2.u.asn1_ellipsis.length = 5;
|
||||
tests[1].val = &c2_2;
|
||||
|
||||
ret += generic_test (tests, ntests, sizeof(TESTChoice2),
|
||||
(generic_encode)encode_TESTChoice2,
|
||||
(generic_length)length_TESTChoice2,
|
||||
(generic_decode)decode_TESTChoice2,
|
||||
(generic_free)free_TESTChoice2,
|
||||
cmp_TESTChoice);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
check_fail_largetag(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, 14, "\x30\x0c\xbf\x87\xff\xff\xff\xff\xff\x7f\x03\x02\x01\x01",
|
||||
"tag overflow"},
|
||||
{NULL, 0, "", "empty buffer"},
|
||||
{NULL, 7, "\x30\x05\xa1\x03\x02\x02\x01",
|
||||
"one too short" },
|
||||
{NULL, 7, "\x30\x04\xa1\x03\x02\x02\x01"
|
||||
"two too short" },
|
||||
{NULL, 7, "\x30\x03\xa1\x03\x02\x02\x01",
|
||||
"three too short" },
|
||||
{NULL, 7, "\x30\x02\xa1\x03\x02\x02\x01",
|
||||
"four too short" },
|
||||
{NULL, 7, "\x30\x01\xa1\x03\x02\x02\x01",
|
||||
"five too short" },
|
||||
{NULL, 7, "\x30\x00\xa1\x03\x02\x02\x01",
|
||||
"six too short" },
|
||||
{NULL, 7, "\x30\x05\xa1\x04\x02\x02\x01",
|
||||
"inner one too long" },
|
||||
{NULL, 7, "\x30\x00\xa1\x02\x02\x02\x01",
|
||||
"inner one too short" },
|
||||
{NULL, 8, "\x30\x05\xbf\x7f\x03\x02\x02\x01",
|
||||
"inner one too short"},
|
||||
{NULL, 8, "\x30\x06\xbf\x64\x03\x02\x01\x01",
|
||||
"wrong tag"},
|
||||
{NULL, 10, "\x30\x08\xbf\x9a\x9b\x38\x03\x02\x01\x01",
|
||||
"still wrong tag"},
|
||||
{NULL, -1, NULL, "overlarger buffer"}
|
||||
};
|
||||
int i;
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
for (i = 0; i < ntests; ++i) {
|
||||
tests[i].val = &values[i];
|
||||
asprintf (&tests[i].name, "AuthorizationData %d", i);
|
||||
values[i].val = emalloc(values[i].len * sizeof(values[i].val[0]));
|
||||
}
|
||||
values[0].val[0].ad_type = 1;
|
||||
values[0].val[0].ad_data.length = 1;
|
||||
values[0].val[0].ad_data.data = static_buf512;
|
||||
return generic_decode_fail(tests, ntests, sizeof(TESTLargeTag),
|
||||
(generic_decode)decode_TESTLargeTag);
|
||||
}
|
||||
|
||||
values[1].val[0].ad_type = 1;
|
||||
values[1].val[0].ad_data.length = 126;
|
||||
values[1].val[0].ad_data.data = static_buf512;
|
||||
|
||||
values[2].val[0].ad_type = 1;
|
||||
values[2].val[0].ad_data.length = 106;
|
||||
values[2].val[0].ad_data.data = static_buf512;
|
||||
static int
|
||||
check_fail_sequence(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, 0, "", "empty buffer"},
|
||||
{NULL, 24,
|
||||
"\x30\x16\xa0\x03\x02\x01\x01\xa1\x08\x30\x06\xbf\x7f\x03\x02\x01\x01"
|
||||
"\x02\x01\x01\xa2\x03\x02\x01\x01"
|
||||
"missing one byte from the end, internal length ok"},
|
||||
{NULL, 25,
|
||||
"\x30\x18\xa0\x03\x02\x01\x01\xa1\x08\x30\x06\xbf\x7f\x03\x02\x01\x01"
|
||||
"\x02\x01\x01\xa2\x03\x02\x01\x01",
|
||||
"inner length one byte too long"},
|
||||
{NULL, 24,
|
||||
"\x30\x17\xa0\x03\x02\x01\x01\xa1\x08\x30\x06\xbf\x7f\x03\x02\x01"
|
||||
"\x01\x02\x01\x01\xa2\x03\x02\x01\x01",
|
||||
"correct buffer but missing one to short"},
|
||||
{NULL, -1, NULL, "overlarger buffer"}
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
values[2].val[1].ad_type = 1;
|
||||
values[2].val[1].ad_data.length = 1;
|
||||
values[2].val[1].ad_data.data = static_buf512;
|
||||
return generic_decode_fail(tests, ntests, sizeof(TESTSeq),
|
||||
(generic_decode)decode_TESTSeq);
|
||||
}
|
||||
|
||||
values[3].val[0].ad_type = 1;
|
||||
values[3].val[0].ad_data.length = 107;
|
||||
values[3].val[0].ad_data.data = static_buf512;
|
||||
static int
|
||||
check_fail_choice(void)
|
||||
{
|
||||
struct test_case tests[] = {
|
||||
{NULL, 6,
|
||||
"\xa1\x02\x02\x01\x01",
|
||||
"one too short"},
|
||||
{NULL, 6,
|
||||
"\xa1\x03\x02\x02\x01",
|
||||
"one too short inner"},
|
||||
{NULL, -1, NULL, "overlarger buffer"}
|
||||
};
|
||||
int ntests = sizeof(tests) / sizeof(*tests);
|
||||
|
||||
values[3].val[1].ad_type = 1;
|
||||
values[3].val[1].ad_data.length = 2;
|
||||
values[3].val[1].ad_data.data = static_buf512;
|
||||
|
||||
return generic_test (tests, ntests, sizeof(AuthorizationData),
|
||||
(generic_encode)encode_AuthorizationData,
|
||||
(generic_length)length_AuthorizationData,
|
||||
(generic_decode)decode_AuthorizationData,
|
||||
cmp_AuthorizationData);
|
||||
return generic_decode_fail(tests, ntests, sizeof(TESTChoice1),
|
||||
(generic_decode)decode_TESTChoice1);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -292,7 +688,20 @@ main(int argc, char **argv)
|
||||
|
||||
ret += test_principal ();
|
||||
ret += test_authenticator();
|
||||
ret += test_AuthorizationData();
|
||||
ret += test_krb_error();
|
||||
ret += test_Name();
|
||||
#if 0
|
||||
ret += check_heim_integer();
|
||||
#endif
|
||||
ret += test_bit_string();
|
||||
|
||||
ret += check_tag_length();
|
||||
ret += test_large_tag();
|
||||
ret += test_choice();
|
||||
|
||||
ret += check_fail_largetag();
|
||||
ret += check_fail_sequence();
|
||||
ret += check_fail_choice();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
142
lib/asn1/der.c
Normal file
142
lib/asn1/der.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "der_locl.h"
|
||||
#include <com_err.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <getarg.h>
|
||||
#include <err.h>
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
||||
static const char *class_names[] = {
|
||||
"UNIV", /* 0 */
|
||||
"APPL", /* 1 */
|
||||
"CONTEXT", /* 2 */
|
||||
"PRIVATE" /* 3 */
|
||||
};
|
||||
|
||||
static const char *type_names[] = {
|
||||
"PRIM", /* 0 */
|
||||
"CONS" /* 1 */
|
||||
};
|
||||
|
||||
static const char *tag_names[] = {
|
||||
"EndOfContent", /* 0 */
|
||||
"Boolean", /* 1 */
|
||||
"Integer", /* 2 */
|
||||
"BitString", /* 3 */
|
||||
"OctetString", /* 4 */
|
||||
"Null", /* 5 */
|
||||
"ObjectID", /* 6 */
|
||||
NULL, /* 7 */
|
||||
NULL, /* 8 */
|
||||
NULL, /* 9 */
|
||||
"Enumerated", /* 10 */
|
||||
NULL, /* 11 */
|
||||
NULL, /* 12 */
|
||||
NULL, /* 13 */
|
||||
NULL, /* 14 */
|
||||
NULL, /* 15 */
|
||||
"Sequence", /* 16 */
|
||||
"Set", /* 17 */
|
||||
NULL, /* 18 */
|
||||
"PrintableString", /* 19 */
|
||||
NULL, /* 20 */
|
||||
NULL, /* 21 */
|
||||
"IA5String", /* 22 */
|
||||
"UTCTime", /* 23 */
|
||||
"GeneralizedTime", /* 24 */
|
||||
NULL, /* 25 */
|
||||
"VisibleString", /* 26 */
|
||||
"GeneralString", /* 27 */
|
||||
NULL, /* 28 */
|
||||
NULL, /* 29 */
|
||||
"BMPString" /* 30 */
|
||||
};
|
||||
|
||||
static int
|
||||
get_type(const char *name, const char *list[], unsigned len)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < len; i++)
|
||||
if (list[i] && strcasecmp(list[i], name) == 0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define SIZEOF_ARRAY(a) (sizeof((a))/sizeof((a)[0]))
|
||||
|
||||
const char *
|
||||
der_get_class_name(unsigned num)
|
||||
{
|
||||
if (num >= SIZEOF_ARRAY(class_names))
|
||||
return NULL;
|
||||
return class_names[num];
|
||||
}
|
||||
|
||||
int
|
||||
der_get_class_num(const char *name)
|
||||
{
|
||||
return get_type(name, class_names, SIZEOF_ARRAY(class_names));
|
||||
}
|
||||
|
||||
const char *
|
||||
der_get_type_name(unsigned num)
|
||||
{
|
||||
if (num >= SIZEOF_ARRAY(type_names))
|
||||
return NULL;
|
||||
return type_names[num];
|
||||
}
|
||||
|
||||
int
|
||||
der_get_type_num(const char *name)
|
||||
{
|
||||
return get_type(name, type_names, SIZEOF_ARRAY(type_names));
|
||||
}
|
||||
|
||||
const char *
|
||||
der_get_tag_name(unsigned num)
|
||||
{
|
||||
if (num >= SIZEOF_ARRAY(tag_names))
|
||||
return NULL;
|
||||
return tag_names[num];
|
||||
}
|
||||
|
||||
int
|
||||
der_get_tag_num(const char *name)
|
||||
{
|
||||
return get_type(name, tag_names, SIZEOF_ARRAY(tag_names));
|
||||
}
|
207
lib/asn1/der.h
207
lib/asn1/der.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2001 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -36,145 +36,208 @@
|
||||
#ifndef __DER_H__
|
||||
#define __DER_H__
|
||||
|
||||
#include <time.h>
|
||||
|
||||
typedef enum {
|
||||
ASN1_C_UNIV = 0,
|
||||
ASN1_C_APPL = 1,
|
||||
ASN1_C_CONTEXT = 2 ,
|
||||
ASN1_C_CONTEXT = 2,
|
||||
ASN1_C_PRIVATE = 3
|
||||
} Der_class;
|
||||
|
||||
typedef enum {PRIM = 0, CONS = 1} Der_type;
|
||||
|
||||
#define MAKE_TAG(CLASS, TYPE, TAG) (((CLASS) << 6) | ((TYPE) << 5) | (TAG))
|
||||
|
||||
/* Universal tags */
|
||||
|
||||
enum {
|
||||
UT_Boolean = 1,
|
||||
UT_Integer = 2,
|
||||
UT_BitString = 3,
|
||||
UT_OctetString = 4,
|
||||
UT_Null = 5,
|
||||
UT_OID = 6,
|
||||
UT_Enumerated = 10,
|
||||
UT_UTF8String = 12,
|
||||
UT_Sequence = 16,
|
||||
UT_Set = 17,
|
||||
UT_PrintableString = 19,
|
||||
UT_IA5String = 22,
|
||||
UT_UTCTime = 23,
|
||||
UT_GeneralizedTime = 24,
|
||||
UT_VisibleString = 26,
|
||||
UT_GeneralString = 27
|
||||
UT_EndOfContent = 0,
|
||||
UT_Boolean = 1,
|
||||
UT_Integer = 2,
|
||||
UT_BitString = 3,
|
||||
UT_OctetString = 4,
|
||||
UT_Null = 5,
|
||||
UT_OID = 6,
|
||||
UT_Enumerated = 10,
|
||||
UT_UTF8String = 12,
|
||||
UT_Sequence = 16,
|
||||
UT_Set = 17,
|
||||
UT_PrintableString = 19,
|
||||
UT_IA5String = 22,
|
||||
UT_UTCTime = 23,
|
||||
UT_GeneralizedTime = 24,
|
||||
UT_VisibleString = 26,
|
||||
UT_GeneralString = 27,
|
||||
/* unsupported types */
|
||||
UT_ObjectDescriptor = 7,
|
||||
UT_External = 8,
|
||||
UT_Real = 9,
|
||||
UT_EmbeddedPDV = 11,
|
||||
UT_RelativeOID = 13,
|
||||
UT_NumericString = 18,
|
||||
UT_TeletexString = 20,
|
||||
UT_VideotexString = 21,
|
||||
UT_GraphicString = 25,
|
||||
UT_UniversalString = 25,
|
||||
UT_BMPString = 30,
|
||||
};
|
||||
|
||||
#define ASN1_INDEFINITE 0xdce0deed
|
||||
|
||||
#ifndef HAVE_TIMEGM
|
||||
time_t timegm (struct tm *);
|
||||
#endif
|
||||
typedef struct asn1_der_time_t {
|
||||
time_t dt_sec;
|
||||
unsigned long dt_nsec;
|
||||
} asn1_der_time_t;
|
||||
|
||||
int time2generalizedtime (time_t t, heim_octet_string *s);
|
||||
typedef struct asn1_ber_time_t {
|
||||
time_t bt_sec;
|
||||
unsigned bt_nsec;
|
||||
int bt_zone;
|
||||
} asn1_ber_time_t;
|
||||
|
||||
int der_get_int (const unsigned char *p, size_t len, int *ret, size_t *size);
|
||||
int der_get_unsigned (const unsigned char *p, size_t len,
|
||||
unsigned *ret, size_t *size);
|
||||
int der_get_integer (const unsigned char *p, size_t len,
|
||||
int *ret, size_t *size);
|
||||
int der_get_heim_integer (const unsigned char *p, size_t len,
|
||||
heim_integer *ret, size_t *size);
|
||||
int der_get_boolean(const unsigned char *p, size_t len,
|
||||
int *data, size_t *size);
|
||||
int der_get_length (const unsigned char *p, size_t len,
|
||||
size_t *val, size_t *size);
|
||||
int der_get_boolean (const unsigned char *p, size_t len,
|
||||
int *data, size_t *size);
|
||||
int der_get_general_string (const unsigned char *p, size_t len,
|
||||
heim_general_string *str, size_t *size);
|
||||
int der_get_utf8string (const unsigned char *p, size_t len,
|
||||
heim_utf8_string *str, size_t *size);
|
||||
int der_get_universal_string (const unsigned char *p, size_t len,
|
||||
heim_universal_string *str, size_t *size);
|
||||
int der_get_bmp_string (const unsigned char *p, size_t len,
|
||||
heim_bmp_string *str, size_t *size);
|
||||
int der_get_printable_string (const unsigned char *p, size_t len,
|
||||
heim_printable_string *str, size_t *size);
|
||||
int der_get_ia5_string (const unsigned char *p, size_t len,
|
||||
heim_ia5_string *str, size_t *size);
|
||||
int der_get_octet_string (const unsigned char *p, size_t len,
|
||||
heim_octet_string *data, size_t *size);
|
||||
int der_get_generalized_time (const unsigned char *p, size_t len,
|
||||
time_t *data, size_t *size);
|
||||
int der_get_generalized_time_der (const unsigned char *p, size_t len,
|
||||
asn1_der_time_t *data, size_t *size);
|
||||
int der_get_generalized_time_ber (const unsigned char *p, size_t len,
|
||||
asn1_ber_time_t *data, size_t *size);
|
||||
int der_get_utctime (const unsigned char *p, size_t len,
|
||||
time_t *data, size_t *size);
|
||||
int der_get_oid (const unsigned char *p, size_t len,
|
||||
heim_oid *data, size_t *size);
|
||||
int der_get_bit_string (const unsigned char *p, size_t len,
|
||||
heim_bit_string *data, size_t *size);
|
||||
int der_get_tag (const unsigned char *p, size_t len,
|
||||
Der_class *class, Der_type *type,
|
||||
int *tag, size_t *size);
|
||||
unsigned int *tag, size_t *size);
|
||||
|
||||
int der_match_tag (const unsigned char *p, size_t len,
|
||||
Der_class class, Der_type type,
|
||||
int tag, size_t *size);
|
||||
unsigned int tag, size_t *size);
|
||||
int der_match_tag_and_length (const unsigned char *p, size_t len,
|
||||
Der_class class, Der_type type, int tag,
|
||||
Der_class class, Der_type type, unsigned int tag,
|
||||
size_t *length_ret, size_t *size);
|
||||
|
||||
int decode_boolean (const unsigned char*, size_t, int*, size_t*);
|
||||
int decode_integer (const unsigned char*, size_t, int*, size_t*);
|
||||
int decode_unsigned (const unsigned char*, size_t, unsigned*, size_t*);
|
||||
int decode_enumerated (const unsigned char*, size_t, unsigned*, size_t*);
|
||||
int decode_general_string (const unsigned char*, size_t,
|
||||
heim_general_string*, size_t*);
|
||||
int decode_oid (const unsigned char *p, size_t len,
|
||||
heim_oid *k, size_t *size);
|
||||
int decode_octet_string (const unsigned char*, size_t,
|
||||
heim_octet_string*, size_t*);
|
||||
int decode_generalized_time (const unsigned char*, size_t, time_t*, size_t*);
|
||||
int decode_nulltype (const unsigned char*, size_t, size_t*);
|
||||
int decode_utf8string (const unsigned char*, size_t,
|
||||
heim_utf8_string*, size_t*);
|
||||
int der_put_unsigned (unsigned char *p, size_t len, const unsigned *val, size_t*);
|
||||
int der_put_integer (unsigned char *p, size_t len, const int *val, size_t*);
|
||||
int der_put_heim_integer (unsigned char *p, size_t len,
|
||||
const heim_integer *val, size_t*);
|
||||
int der_put_boolean (unsigned char *p, size_t len, const int *val, size_t*);
|
||||
|
||||
int der_put_int (unsigned char *p, size_t len, int val, size_t*);
|
||||
int der_put_length (unsigned char *p, size_t len, size_t val, size_t*);
|
||||
int der_put_boolean (unsigned char *p, size_t len, const int *data, size_t*);
|
||||
int der_put_general_string (unsigned char *p, size_t len,
|
||||
const heim_general_string *str, size_t*);
|
||||
int der_put_utf8string (unsigned char *p, size_t len,
|
||||
const heim_utf8_string *str, size_t*);
|
||||
int der_put_universal_string (unsigned char *p, size_t len,
|
||||
const heim_universal_string *str, size_t*);
|
||||
int der_put_bmp_string (unsigned char *p, size_t len,
|
||||
const heim_bmp_string *str, size_t*);
|
||||
int der_put_printable_string (unsigned char *p, size_t len,
|
||||
const heim_printable_string *str, size_t*);
|
||||
int der_put_ia5_string (unsigned char *p, size_t len,
|
||||
const heim_ia5_string *str, size_t*);
|
||||
int der_put_octet_string (unsigned char *p, size_t len,
|
||||
const heim_octet_string *data, size_t*);
|
||||
int der_put_generalized_time (unsigned char *p, size_t len,
|
||||
const time_t *data, size_t *size);
|
||||
int der_put_utctime (unsigned char *p, size_t len,
|
||||
const time_t *data, size_t *size);
|
||||
int der_put_oid (unsigned char *p, size_t len,
|
||||
const heim_oid *data, size_t *size);
|
||||
int der_put_bit_string (unsigned char *p, size_t len,
|
||||
const heim_bit_string *data, size_t *size);
|
||||
int der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
|
||||
int tag, size_t*);
|
||||
unsigned int tag, size_t*);
|
||||
int der_put_length_and_tag (unsigned char*, size_t, size_t,
|
||||
Der_class, Der_type, int, size_t*);
|
||||
|
||||
int encode_boolean (unsigned char *p, size_t len,
|
||||
const int *data, size_t*);
|
||||
int encode_integer (unsigned char *p, size_t len,
|
||||
const int *data, size_t*);
|
||||
int encode_unsigned (unsigned char *p, size_t len,
|
||||
const unsigned *data, size_t*);
|
||||
int encode_enumerated (unsigned char *p, size_t len,
|
||||
const unsigned *data, size_t*);
|
||||
int encode_general_string (unsigned char *p, size_t len,
|
||||
const heim_general_string *data, size_t*);
|
||||
int encode_octet_string (unsigned char *p, size_t len,
|
||||
const heim_octet_string *k, size_t*);
|
||||
int encode_oid (unsigned char *p, size_t len,
|
||||
const heim_oid *k, size_t*);
|
||||
int encode_generalized_time (unsigned char *p, size_t len,
|
||||
const time_t *t, size_t*);
|
||||
int encode_nulltype (unsigned char*, size_t, size_t*);
|
||||
int encode_utf8string (unsigned char*, size_t,
|
||||
const heim_utf8_string*, size_t*);
|
||||
Der_class, Der_type, unsigned int, size_t*);
|
||||
|
||||
void free_integer (int *num);
|
||||
void free_heim_integer (heim_integer *num);
|
||||
void free_octet_string (heim_octet_string *k);
|
||||
void free_general_string (heim_general_string *str);
|
||||
void free_octet_string (heim_octet_string *k);
|
||||
void free_oid (heim_oid *k);
|
||||
void free_bit_string (heim_bit_string *k);
|
||||
void free_generalized_time (time_t *t);
|
||||
void free_utctime (time_t *t);
|
||||
void free_utf8string (heim_utf8_string*);
|
||||
void free_printable_string (heim_printable_string*);
|
||||
void free_ia5_string (heim_ia5_string*);
|
||||
void free_universal_string (heim_universal_string*);
|
||||
void free_bmp_string (heim_bmp_string*);
|
||||
|
||||
size_t length_len (size_t len);
|
||||
size_t length_boolean (const int *data);
|
||||
size_t length_integer (const int *data);
|
||||
size_t length_heim_integer (const heim_integer *data);
|
||||
size_t length_unsigned (const unsigned *data);
|
||||
size_t length_enumerated (const unsigned *data);
|
||||
size_t length_general_string (const heim_general_string *data);
|
||||
size_t length_octet_string (const heim_octet_string *k);
|
||||
size_t length_oid (const heim_oid *k);
|
||||
size_t length_bit_string (const heim_bit_string *k);
|
||||
size_t length_generalized_time (const time_t *t);
|
||||
size_t length_nulltype (void);
|
||||
size_t length_utctime (const time_t *t);
|
||||
size_t length_utf8string (const heim_utf8_string*);
|
||||
size_t length_printable_string (const heim_printable_string*);
|
||||
size_t length_ia5_string (const heim_ia5_string*);
|
||||
size_t length_bmp_string (const heim_bmp_string*);
|
||||
size_t length_universal_string (const heim_universal_string*);
|
||||
size_t length_boolean (const int*);
|
||||
|
||||
int copy_heim_integer (const heim_integer *, heim_integer *);
|
||||
int copy_general_string (const heim_general_string *, heim_general_string *);
|
||||
int copy_octet_string (const heim_octet_string *, heim_octet_string *);
|
||||
int copy_oid (const heim_oid *from, heim_oid *to);
|
||||
int copy_nulltype (void *, void *);
|
||||
int copy_bit_string (const heim_bit_string *from, heim_bit_string *to);
|
||||
int copy_utf8string (const heim_utf8_string*, heim_utf8_string*);
|
||||
int copy_printable_string (const heim_printable_string*,heim_printable_string*);
|
||||
int copy_ia5_string (const heim_ia5_string*,heim_ia5_string*);
|
||||
int copy_universal_string(const heim_universal_string*,heim_universal_string*);
|
||||
int copy_bmp_string (const heim_bmp_string*,heim_bmp_string*);
|
||||
|
||||
int heim_oid_cmp(const heim_oid *, const heim_oid *);
|
||||
int heim_octet_string_cmp(const heim_octet_string *,const heim_octet_string *);
|
||||
int heim_bit_string_cmp(const heim_bit_string *, const heim_bit_string *);
|
||||
int heim_integer_cmp(const heim_integer *, const heim_integer *);
|
||||
int heim_bmp_string_cmp(const heim_bmp_string *, const heim_bmp_string *);
|
||||
int heim_universal_string_cmp(const heim_universal_string *,
|
||||
const heim_universal_string *);
|
||||
|
||||
int fix_dce(size_t reallen, size_t *len);
|
||||
int der_parse_oid(const char *, heim_oid *);
|
||||
|
||||
int _heim_fix_dce(size_t reallen, size_t *len);
|
||||
int _heim_der_set_sort(const void *, const void *);
|
||||
int _heim_time2generalizedtime (time_t, heim_octet_string *, int);
|
||||
|
||||
const char * der_get_class_name(unsigned);
|
||||
int der_get_class_num(const char *);
|
||||
const char * der_get_type_name(unsigned);
|
||||
int der_get_type_num(const char *);
|
||||
const char * der_get_tag_name(unsigned);
|
||||
int der_get_tag_num(const char *);
|
||||
|
||||
#endif /* __DER_H__ */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003 - 2004 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 2003-2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -33,8 +33,6 @@
|
||||
|
||||
#include "der_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
int
|
||||
heim_oid_cmp(const heim_oid *p, const heim_oid *q)
|
||||
{
|
||||
@@ -52,3 +50,48 @@ heim_octet_string_cmp(const heim_octet_string *p, const heim_octet_string *q)
|
||||
return p->length - q->length;
|
||||
return memcmp(p->data, q->data, p->length);
|
||||
}
|
||||
|
||||
int
|
||||
heim_bit_string_cmp(const heim_bit_string *p, const heim_bit_string *q)
|
||||
{
|
||||
int i, r1, r2;
|
||||
if (p->length != q->length)
|
||||
return p->length - q->length;
|
||||
i = memcmp(p->data, q->data, p->length / 8);
|
||||
if (i)
|
||||
return i;
|
||||
i = p->length / 8;
|
||||
r1 = ((unsigned char *)p->data)[i];
|
||||
r2 = ((unsigned char *)q->data)[i];
|
||||
i = 8 - p->length % 8;
|
||||
r1 = r1 >> i;
|
||||
r2 = r2 >> i;
|
||||
return r1 - r2;
|
||||
}
|
||||
|
||||
int
|
||||
heim_integer_cmp(const heim_integer *p, const heim_integer *q)
|
||||
{
|
||||
if (p->length != q->length)
|
||||
return p->length - q->length;
|
||||
if (p->negative != q->negative)
|
||||
return p->negative - q->negative;
|
||||
return memcmp(p->data, q->data, p->length);
|
||||
}
|
||||
|
||||
int
|
||||
heim_bmp_string_cmp(const heim_bmp_string *p, const heim_bmp_string *q)
|
||||
{
|
||||
if (p->length != q->length)
|
||||
return p->length - q->length;
|
||||
return memcmp(p->data, q->data, q->length * sizeof(q->data[0]));
|
||||
}
|
||||
|
||||
int
|
||||
heim_universal_string_cmp(const heim_universal_string *p,
|
||||
const heim_universal_string *q)
|
||||
{
|
||||
if (p->length != q->length)
|
||||
return p->length - q->length;
|
||||
return memcmp(p->data, q->data, q->length * sizeof(q->data[0]));
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2001 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -44,6 +44,49 @@ copy_general_string (const heim_general_string *from, heim_general_string *to)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
copy_utf8string (const heim_utf8_string *from, heim_utf8_string *to)
|
||||
{
|
||||
return copy_general_string(from, to);
|
||||
}
|
||||
|
||||
int
|
||||
copy_printable_string (const heim_printable_string *from,
|
||||
heim_printable_string *to)
|
||||
{
|
||||
return copy_general_string(from, to);
|
||||
}
|
||||
|
||||
int
|
||||
copy_ia5_string (const heim_printable_string *from,
|
||||
heim_printable_string *to)
|
||||
{
|
||||
return copy_general_string(from, to);
|
||||
}
|
||||
|
||||
int
|
||||
copy_bmp_string (const heim_bmp_string *from, heim_bmp_string *to)
|
||||
{
|
||||
to->length = from->length;
|
||||
to->data = malloc(to->length * sizeof(to->data[0]));
|
||||
if(to->length != 0 && to->data == NULL)
|
||||
return ENOMEM;
|
||||
memcpy(to->data, from->data, to->length * sizeof(to->data[0]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
copy_universal_string (const heim_universal_string *from,
|
||||
heim_universal_string *to)
|
||||
{
|
||||
to->length = from->length;
|
||||
to->data = malloc(to->length * sizeof(to->data[0]));
|
||||
if(to->length != 0 && to->data == NULL)
|
||||
return ENOMEM;
|
||||
memcpy(to->data, from->data, to->length * sizeof(to->data[0]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
copy_octet_string (const heim_octet_string *from, heim_octet_string *to)
|
||||
{
|
||||
@@ -55,6 +98,17 @@ copy_octet_string (const heim_octet_string *from, heim_octet_string *to)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
copy_heim_integer (const heim_integer *from, heim_integer *to)
|
||||
{
|
||||
to->length = from->length;
|
||||
to->data = malloc(to->length);
|
||||
if(to->length != 0 && to->data == NULL)
|
||||
return ENOMEM;
|
||||
memcpy(to->data, from->data, to->length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
copy_oid (const heim_oid *from, heim_oid *to)
|
||||
{
|
||||
@@ -66,3 +120,17 @@ copy_oid (const heim_oid *from, heim_oid *to)
|
||||
to->length * sizeof(*to->components));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
copy_bit_string (const heim_bit_string *from, heim_bit_string *to)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = (from->length + 7) / 8;
|
||||
to->length = from->length;
|
||||
to->data = malloc(len);
|
||||
if(len != 0 && to->data == NULL)
|
||||
return ENOMEM;
|
||||
memcpy(to->data, from->data, len);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2003 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -42,11 +42,56 @@ free_general_string (heim_general_string *str)
|
||||
*str = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
free_utf8string (heim_utf8_string *str)
|
||||
{
|
||||
free(*str);
|
||||
*str = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
free_printable_string (heim_printable_string *str)
|
||||
{
|
||||
free(*str);
|
||||
*str = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
free_ia5_string (heim_ia5_string *str)
|
||||
{
|
||||
free_general_string(str);
|
||||
}
|
||||
|
||||
void
|
||||
free_bmp_string (heim_bmp_string *k)
|
||||
{
|
||||
free(k->data);
|
||||
k->data = NULL;
|
||||
k->length = 0;
|
||||
}
|
||||
|
||||
void
|
||||
free_universal_string (heim_universal_string *k)
|
||||
{
|
||||
free(k->data);
|
||||
k->data = NULL;
|
||||
k->length = 0;
|
||||
}
|
||||
|
||||
void
|
||||
free_octet_string (heim_octet_string *k)
|
||||
{
|
||||
free(k->data);
|
||||
k->data = NULL;
|
||||
k->length = 0;
|
||||
}
|
||||
|
||||
void
|
||||
free_heim_integer (heim_integer *k)
|
||||
{
|
||||
free(k->data);
|
||||
k->data = NULL;
|
||||
k->length = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -54,4 +99,13 @@ free_oid (heim_oid *k)
|
||||
{
|
||||
free(k->components);
|
||||
k->components = NULL;
|
||||
k->length = 0;
|
||||
}
|
||||
|
||||
void
|
||||
free_bit_string (heim_bit_string *k)
|
||||
{
|
||||
free(k->data);
|
||||
k->data = NULL;
|
||||
k->length = 0;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2004 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -45,13 +45,18 @@ RCSID("$Id$");
|
||||
* Either 0 or an error code is returned.
|
||||
*/
|
||||
|
||||
static int
|
||||
int
|
||||
der_get_unsigned (const unsigned char *p, size_t len,
|
||||
unsigned *ret, size_t *size)
|
||||
{
|
||||
unsigned val = 0;
|
||||
size_t oldlen = len;
|
||||
|
||||
if (len == sizeof(unsigned) + 1 && p[0] == 0)
|
||||
;
|
||||
else if (len > sizeof(unsigned))
|
||||
return ASN1_OVERRUN;
|
||||
|
||||
while (len--)
|
||||
val = val * 256 + *p++;
|
||||
*ret = val;
|
||||
@@ -60,12 +65,15 @@ der_get_unsigned (const unsigned char *p, size_t len,
|
||||
}
|
||||
|
||||
int
|
||||
der_get_int (const unsigned char *p, size_t len,
|
||||
int *ret, size_t *size)
|
||||
der_get_integer (const unsigned char *p, size_t len,
|
||||
int *ret, size_t *size)
|
||||
{
|
||||
int val = 0;
|
||||
size_t oldlen = len;
|
||||
|
||||
if (len > sizeof(int))
|
||||
return ASN1_OVERRUN;
|
||||
|
||||
if (len > 0) {
|
||||
val = (signed char)*p++;
|
||||
while (--len)
|
||||
@@ -76,19 +84,6 @@ der_get_int (const unsigned char *p, size_t len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size)
|
||||
{
|
||||
if(len < 1)
|
||||
return ASN1_OVERRUN;
|
||||
if(*p != 0)
|
||||
*data = 1;
|
||||
else
|
||||
*data = 0;
|
||||
*size = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_length (const unsigned char *p, size_t len,
|
||||
size_t *val, size_t *size)
|
||||
@@ -123,12 +118,28 @@ der_get_length (const unsigned char *p, size_t len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size)
|
||||
{
|
||||
if(len < 1)
|
||||
return ASN1_OVERRUN;
|
||||
if(*p != 0)
|
||||
*data = 1;
|
||||
else
|
||||
*data = 0;
|
||||
*size = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_general_string (const unsigned char *p, size_t len,
|
||||
heim_general_string *str, size_t *size)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (len > SIZE_T_MAX - 1)
|
||||
return ASN1_BAD_LENGTH;
|
||||
|
||||
s = malloc (len + 1);
|
||||
if (s == NULL)
|
||||
return ENOMEM;
|
||||
@@ -139,6 +150,70 @@ der_get_general_string (const unsigned char *p, size_t len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_utf8string (const unsigned char *p, size_t len,
|
||||
heim_utf8_string *str, size_t *size)
|
||||
{
|
||||
return der_get_general_string(p, len, str, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_get_printable_string (const unsigned char *p, size_t len,
|
||||
heim_printable_string *str, size_t *size)
|
||||
{
|
||||
return der_get_general_string(p, len, str, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_get_ia5_string (const unsigned char *p, size_t len,
|
||||
heim_ia5_string *str, size_t *size)
|
||||
{
|
||||
return der_get_general_string(p, len, str, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_get_bmp_string (const unsigned char *p, size_t len,
|
||||
heim_bmp_string *data, size_t *size)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (len & 1)
|
||||
return ASN1_BAD_FORMAT;
|
||||
data->length = len / 2;
|
||||
data->data = malloc(data->length * sizeof(data->data[0]));
|
||||
if (data->data == NULL && data->length != 0)
|
||||
return ENOMEM;
|
||||
|
||||
for (i = 0; i < data->length; i++) {
|
||||
data->data[i] = (p[0] << 8) | p[1];
|
||||
p += 2;
|
||||
}
|
||||
if (size) *size = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_universal_string (const unsigned char *p, size_t len,
|
||||
heim_universal_string *data, size_t *size)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (len & 3)
|
||||
return ASN1_BAD_FORMAT;
|
||||
data->length = len / 4;
|
||||
data->data = malloc(data->length * sizeof(data->data[0]));
|
||||
if (data->data == NULL && data->length != 0)
|
||||
return ENOMEM;
|
||||
|
||||
for (i = 0; i < data->length; i++) {
|
||||
data->data[i] = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
|
||||
p += 4;
|
||||
}
|
||||
if (size) *size = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_octet_string (const unsigned char *p, size_t len,
|
||||
heim_octet_string *data, size_t *size)
|
||||
@@ -152,6 +227,108 @@ der_get_octet_string (const unsigned char *p, size_t len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_heim_integer (const unsigned char *p, size_t len,
|
||||
heim_integer *data, size_t *size)
|
||||
{
|
||||
data->length = 0;
|
||||
data->negative = 0;
|
||||
data->data = NULL;
|
||||
|
||||
if (len == 0) {
|
||||
if (size)
|
||||
*size = 0;
|
||||
return 0;
|
||||
}
|
||||
if (p[0] & 0x80) {
|
||||
data->negative = 1;
|
||||
|
||||
return ASN1_OVERRUN;
|
||||
} else {
|
||||
data->negative = 0;
|
||||
data->length = len;
|
||||
|
||||
if (p[0] == 0 && data->length != 1) {
|
||||
p++;
|
||||
data->length--;
|
||||
}
|
||||
data->data = malloc(data->length);
|
||||
if (data->data == NULL) {
|
||||
data->length = 0;
|
||||
return ENOMEM;
|
||||
}
|
||||
memcpy(data->data, p, data->length);
|
||||
}
|
||||
if (size)
|
||||
*size = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
generalizedtime2time (const char *s, time_t *t)
|
||||
{
|
||||
struct tm tm;
|
||||
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
if (sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
|
||||
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
|
||||
&tm.tm_min, &tm.tm_sec) != 6) {
|
||||
if (sscanf (s, "%02d%02d%02d%02d%02d%02dZ",
|
||||
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
|
||||
&tm.tm_min, &tm.tm_sec) != 6)
|
||||
return ASN1_BAD_TIMEFORMAT;
|
||||
if (tm.tm_year < 50)
|
||||
tm.tm_year += 2000;
|
||||
else
|
||||
tm.tm_year += 1900;
|
||||
}
|
||||
tm.tm_year -= 1900;
|
||||
tm.tm_mon -= 1;
|
||||
*t = timegm (&tm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
der_get_time (const unsigned char *p, size_t len,
|
||||
time_t *data, size_t *size)
|
||||
{
|
||||
heim_octet_string k;
|
||||
char *times;
|
||||
size_t ret = 0;
|
||||
size_t l;
|
||||
int e;
|
||||
|
||||
e = der_get_octet_string (p, len, &k, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
times = realloc(k.data, k.length + 1);
|
||||
if (times == NULL){
|
||||
free(k.data);
|
||||
return ENOMEM;
|
||||
}
|
||||
times[k.length] = 0;
|
||||
e = generalizedtime2time(times, data);
|
||||
free (times);
|
||||
if(size) *size = ret;
|
||||
return e;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_generalized_time (const unsigned char *p, size_t len,
|
||||
time_t *data, size_t *size)
|
||||
{
|
||||
return der_get_time(p, len, data, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_get_utctime (const unsigned char *p, size_t len,
|
||||
time_t *data, size_t *size)
|
||||
{
|
||||
return der_get_time(p, len, data, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_get_oid (const unsigned char *p, size_t len,
|
||||
heim_oid *data, size_t *size)
|
||||
@@ -162,6 +339,9 @@ der_get_oid (const unsigned char *p, size_t len,
|
||||
if (len < 1)
|
||||
return ASN1_OVERRUN;
|
||||
|
||||
if (len > SIZE_T_MAX - 1)
|
||||
return ASN1_BAD_LENGTH;
|
||||
|
||||
data->components = malloc((len + 1) * sizeof(*data->components));
|
||||
if (data->components == NULL)
|
||||
return ENOMEM;
|
||||
@@ -170,15 +350,21 @@ der_get_oid (const unsigned char *p, size_t len,
|
||||
--len;
|
||||
++p;
|
||||
for (n = 2; len > 0; ++n) {
|
||||
unsigned u = 0;
|
||||
unsigned u = 0, u1;
|
||||
|
||||
do {
|
||||
--len;
|
||||
u = u * 128 + (*p++ % 128);
|
||||
u1 = u * 128 + (*p++ % 128);
|
||||
/* check that we don't overflow the element */
|
||||
if (u1 < u) {
|
||||
free_oid(data);
|
||||
return ASN1_OVERRUN;
|
||||
}
|
||||
u = u1;
|
||||
} while (len > 0 && p[-1] & 0x80);
|
||||
data->components[n] = u;
|
||||
}
|
||||
if (len > 0 && p[-1] & 0x80) {
|
||||
if (n > 2 && p[-1] & 0x80) {
|
||||
free_oid (data);
|
||||
return ASN1_OVERRUN;
|
||||
}
|
||||
@@ -191,21 +377,39 @@ der_get_oid (const unsigned char *p, size_t len,
|
||||
int
|
||||
der_get_tag (const unsigned char *p, size_t len,
|
||||
Der_class *class, Der_type *type,
|
||||
int *tag, size_t *size)
|
||||
unsigned int *tag, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
if (len < 1)
|
||||
return ASN1_OVERRUN;
|
||||
*class = (Der_class)(((*p) >> 6) & 0x03);
|
||||
*type = (Der_type)(((*p) >> 5) & 0x01);
|
||||
*tag = (*p) & 0x1F;
|
||||
if(size) *size = 1;
|
||||
*tag = (*p) & 0x1f;
|
||||
p++; len--; ret++;
|
||||
if(*tag == 0x1f) {
|
||||
unsigned int continuation;
|
||||
unsigned int tag1;
|
||||
*tag = 0;
|
||||
do {
|
||||
if(len < 1)
|
||||
return ASN1_OVERRUN;
|
||||
continuation = *p & 128;
|
||||
tag1 = *tag * 128 + (*p % 128);
|
||||
/* check that we don't overflow the tag */
|
||||
if (tag1 < *tag)
|
||||
return ASN1_OVERFLOW;
|
||||
*tag = tag1;
|
||||
p++; len--; ret++;
|
||||
} while(continuation);
|
||||
}
|
||||
if(size) *size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_match_tag (const unsigned char *p, size_t len,
|
||||
Der_class class, Der_type type,
|
||||
int tag, size_t *size)
|
||||
unsigned int tag, size_t *size)
|
||||
{
|
||||
size_t l;
|
||||
Der_class thisclass;
|
||||
@@ -227,7 +431,7 @@ der_match_tag (const unsigned char *p, size_t len,
|
||||
|
||||
int
|
||||
der_match_tag_and_length (const unsigned char *p, size_t len,
|
||||
Der_class class, Der_type type, int tag,
|
||||
Der_class class, Der_type type, unsigned int tag,
|
||||
size_t *length_ret, size_t *size)
|
||||
{
|
||||
size_t l, ret = 0;
|
||||
@@ -238,7 +442,6 @@ der_match_tag_and_length (const unsigned char *p, size_t len,
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
|
||||
e = der_get_length (p, len, length_ret, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
@@ -248,281 +451,21 @@ der_match_tag_and_length (const unsigned char *p, size_t len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
decode_boolean (const unsigned char *p, size_t len,
|
||||
int *num, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t l, reallen;
|
||||
int e;
|
||||
|
||||
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_Boolean, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
|
||||
e = der_get_length (p, len, &reallen, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if (reallen > len)
|
||||
return ASN1_OVERRUN;
|
||||
|
||||
e = der_get_boolean (p, reallen, num, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if(size) *size = ret;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Old versions of DCE was based on a very early beta of the MIT code,
|
||||
* which used MAVROS for ASN.1 encoding. MAVROS had the interesting
|
||||
* feature that it encoded data in the forward direction, which has
|
||||
* it's problems, since you have no idea how long the data will be
|
||||
* until after you're done. MAVROS solved this by reserving one byte
|
||||
* for length, and later, if the actual length was longer, it reverted
|
||||
* to indefinite, BER style, lengths. The version of MAVROS used by
|
||||
* the DCE people could apparently generate correct X.509 DER encodings, and
|
||||
* did this by making space for the length after encoding, but
|
||||
* unfortunately this feature wasn't used with Kerberos.
|
||||
*/
|
||||
|
||||
int
|
||||
decode_integer (const unsigned char *p, size_t len,
|
||||
int *num, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t l, reallen;
|
||||
int e;
|
||||
|
||||
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_Integer, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
|
||||
e = der_get_length (p, len, &reallen, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if (reallen > len)
|
||||
return ASN1_OVERRUN;
|
||||
|
||||
e = der_get_int (p, reallen, num, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if(size) *size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
decode_unsigned (const unsigned char *p, size_t len,
|
||||
unsigned *num, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t l, reallen;
|
||||
int e;
|
||||
|
||||
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_Integer, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
|
||||
e = der_get_length (p, len, &reallen, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if (reallen > len)
|
||||
return ASN1_OVERRUN;
|
||||
|
||||
e = der_get_unsigned (p, reallen, num, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if(size) *size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
decode_enumerated (const unsigned char *p, size_t len,
|
||||
unsigned *num, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t l, reallen;
|
||||
int e;
|
||||
|
||||
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_Enumerated, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
|
||||
e = der_get_length (p, len, &reallen, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if (reallen > len)
|
||||
return ASN1_OVERRUN;
|
||||
|
||||
e = der_get_int (p, reallen, num, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if(size) *size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
decode_general_string (const unsigned char *p, size_t len,
|
||||
heim_general_string *str, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t l, reallen;
|
||||
int e;
|
||||
|
||||
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_GeneralString, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
|
||||
e = der_get_length (p, len, &reallen, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if (len < reallen)
|
||||
return ASN1_OVERRUN;
|
||||
|
||||
e = der_get_general_string (p, reallen, str, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if(size) *size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
decode_octet_string (const unsigned char *p, size_t len,
|
||||
heim_octet_string *k, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t l, reallen;
|
||||
int e;
|
||||
|
||||
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_OctetString, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
|
||||
e = der_get_length (p, len, &reallen, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if (len < reallen)
|
||||
return ASN1_OVERRUN;
|
||||
|
||||
e = der_get_octet_string (p, reallen, k, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if(size) *size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
decode_oid (const unsigned char *p, size_t len,
|
||||
heim_oid *k, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t l, reallen;
|
||||
int e;
|
||||
|
||||
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_OID, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
|
||||
e = der_get_length (p, len, &reallen, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if (len < reallen)
|
||||
return ASN1_OVERRUN;
|
||||
|
||||
e = der_get_oid (p, reallen, k, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if(size) *size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
generalizedtime2time (const char *s, time_t *t)
|
||||
{
|
||||
struct tm tm;
|
||||
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
|
||||
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
|
||||
&tm.tm_min, &tm.tm_sec);
|
||||
tm.tm_year -= 1900;
|
||||
tm.tm_mon -= 1;
|
||||
*t = timegm (&tm);
|
||||
}
|
||||
|
||||
int
|
||||
decode_generalized_time (const unsigned char *p, size_t len,
|
||||
time_t *t, size_t *size)
|
||||
{
|
||||
heim_octet_string k;
|
||||
char *times;
|
||||
size_t ret = 0;
|
||||
size_t l, reallen;
|
||||
int e;
|
||||
|
||||
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_GeneralizedTime, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
|
||||
e = der_get_length (p, len, &reallen, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if (len < reallen)
|
||||
return ASN1_OVERRUN;
|
||||
|
||||
e = der_get_octet_string (p, reallen, &k, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
times = realloc(k.data, k.length + 1);
|
||||
if (times == NULL){
|
||||
free(k.data);
|
||||
return ENOMEM;
|
||||
}
|
||||
times[k.length] = 0;
|
||||
generalizedtime2time (times, t);
|
||||
free (times);
|
||||
if(size) *size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fix_dce(size_t reallen, size_t *len)
|
||||
_heim_fix_dce(size_t reallen, size_t *len)
|
||||
{
|
||||
if(reallen == ASN1_INDEFINITE)
|
||||
return 1;
|
||||
@@ -531,3 +474,25 @@ fix_dce(size_t reallen, size_t *len)
|
||||
*len = reallen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_bit_string (const unsigned char *p, size_t len,
|
||||
heim_bit_string *data, size_t *size)
|
||||
{
|
||||
if (len < 1)
|
||||
return ASN1_OVERRUN;
|
||||
if (p[0] > 7)
|
||||
return ASN1_BAD_FORMAT;
|
||||
if (len - 1 == 0 && p[0] != 0)
|
||||
return ASN1_BAD_FORMAT;
|
||||
if (len - 1 > SIZE_T_MAX / 8)
|
||||
return ASN1_OVERRUN;
|
||||
data->length = (len - 1) * 8;
|
||||
data->data = malloc(len - 1);
|
||||
if (data->data == NULL && (len - 1) != 0)
|
||||
return ENOMEM;
|
||||
memcpy (data->data, p + 1, len - 1);
|
||||
data->length -= p[0];
|
||||
if(size) *size = len;
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997-2003 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997-2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -39,11 +39,17 @@ size_t
|
||||
_heim_len_unsigned (unsigned val)
|
||||
{
|
||||
size_t ret = 0;
|
||||
int last_val_gt_128;
|
||||
|
||||
do {
|
||||
++ret;
|
||||
last_val_gt_128 = (val >= 128);
|
||||
val /= 256;
|
||||
} while (val);
|
||||
|
||||
if(last_val_gt_128)
|
||||
ret++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -83,12 +89,10 @@ len_oid (const heim_oid *oid)
|
||||
for (n = 2; n < oid->length; ++n) {
|
||||
unsigned u = oid->components[n];
|
||||
|
||||
++ret;
|
||||
u /= 128;
|
||||
while (u > 0) {
|
||||
do {
|
||||
++ret;
|
||||
u /= 128;
|
||||
}
|
||||
} while(u > 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -98,68 +102,91 @@ length_len (size_t len)
|
||||
{
|
||||
if (len < 128)
|
||||
return 1;
|
||||
else
|
||||
return _heim_len_unsigned (len) + 1;
|
||||
}
|
||||
|
||||
size_t
|
||||
length_boolean (const int *data)
|
||||
{
|
||||
return 1 + length_len(1) + 1;
|
||||
else {
|
||||
int ret = 0;
|
||||
do {
|
||||
++ret;
|
||||
len /= 256;
|
||||
} while (len);
|
||||
return ret + 1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
length_integer (const int *data)
|
||||
{
|
||||
size_t len = _heim_len_int (*data);
|
||||
|
||||
return 1 + length_len(len) + len;
|
||||
return _heim_len_int (*data);
|
||||
}
|
||||
|
||||
size_t
|
||||
length_unsigned (const unsigned *data)
|
||||
{
|
||||
unsigned val = *data;
|
||||
size_t len = 0;
|
||||
|
||||
while (val > 255) {
|
||||
++len;
|
||||
val /= 256;
|
||||
}
|
||||
len++;
|
||||
if (val >= 128)
|
||||
len++;
|
||||
return 1 + length_len(len) + len;
|
||||
return _heim_len_unsigned(*data);
|
||||
}
|
||||
|
||||
size_t
|
||||
length_enumerated (const unsigned *data)
|
||||
{
|
||||
size_t len = _heim_len_int (*data);
|
||||
|
||||
return 1 + length_len(len) + len;
|
||||
return _heim_len_int (*data);
|
||||
}
|
||||
|
||||
size_t
|
||||
length_general_string (const heim_general_string *data)
|
||||
{
|
||||
char *str = *data;
|
||||
size_t len = strlen(str);
|
||||
return 1 + length_len(len) + len;
|
||||
return strlen(*data);
|
||||
}
|
||||
|
||||
size_t
|
||||
length_utf8string (const heim_utf8_string *data)
|
||||
{
|
||||
return strlen(*data);
|
||||
}
|
||||
|
||||
size_t
|
||||
length_printable_string (const heim_printable_string *data)
|
||||
{
|
||||
return strlen(*data);
|
||||
}
|
||||
|
||||
size_t
|
||||
length_ia5_string (const heim_ia5_string *data)
|
||||
{
|
||||
return strlen(*data);
|
||||
}
|
||||
|
||||
size_t
|
||||
length_bmp_string (const heim_bmp_string *data)
|
||||
{
|
||||
return data->length * 2;
|
||||
}
|
||||
|
||||
size_t
|
||||
length_universal_string (const heim_universal_string *data)
|
||||
{
|
||||
return data->length * 4;
|
||||
}
|
||||
|
||||
size_t
|
||||
length_octet_string (const heim_octet_string *k)
|
||||
{
|
||||
return 1 + length_len(k->length) + k->length;
|
||||
return k->length;
|
||||
}
|
||||
|
||||
size_t
|
||||
length_heim_integer (const heim_integer *k)
|
||||
{
|
||||
if (k->length == 0)
|
||||
return 1;
|
||||
if (k->negative)
|
||||
return k->length + ((((unsigned char *)k->data)[0] & 0x80) ? 0 : 1);
|
||||
else
|
||||
return k->length + ((((unsigned char *)k->data)[0] & 0x80) ? 1 : 0);
|
||||
}
|
||||
|
||||
size_t
|
||||
length_oid (const heim_oid *k)
|
||||
{
|
||||
size_t len = len_oid (k);
|
||||
|
||||
return 1 + length_len(len) + len;
|
||||
return len_oid (k);
|
||||
}
|
||||
|
||||
size_t
|
||||
@@ -168,8 +195,32 @@ length_generalized_time (const time_t *t)
|
||||
heim_octet_string k;
|
||||
size_t ret;
|
||||
|
||||
time2generalizedtime (*t, &k);
|
||||
ret = 1 + length_len(k.length) + k.length;
|
||||
free (k.data);
|
||||
_heim_time2generalizedtime (*t, &k, 1);
|
||||
ret = k.length;
|
||||
free(k.data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
length_utctime (const time_t *t)
|
||||
{
|
||||
heim_octet_string k;
|
||||
size_t ret;
|
||||
|
||||
_heim_time2generalizedtime (*t, &k, 0);
|
||||
ret = k.length;
|
||||
free(k.data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
length_boolean (const int *k)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t
|
||||
length_bit_string (const heim_bit_string *k)
|
||||
{
|
||||
return (k->length + 7) / 8 + 1;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2001 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2002, 2004 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -53,6 +53,10 @@
|
||||
#include <asn1_err.h>
|
||||
#include <der.h>
|
||||
|
||||
#ifndef HAVE_TIMEGM
|
||||
time_t timegm (struct tm *);
|
||||
#endif
|
||||
|
||||
size_t _heim_len_unsigned (unsigned);
|
||||
size_t _heim_len_int (int);
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997-2003 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997-2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -43,10 +43,11 @@ RCSID("$Id$");
|
||||
* The return value is 0 or an error.
|
||||
*/
|
||||
|
||||
static int
|
||||
der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size)
|
||||
int
|
||||
der_put_unsigned (unsigned char *p, size_t len, const unsigned *v, size_t *size)
|
||||
{
|
||||
unsigned char *base = p;
|
||||
unsigned val = *v;
|
||||
|
||||
if (val) {
|
||||
while (len > 0 && val) {
|
||||
@@ -57,6 +58,11 @@ der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size)
|
||||
if (val != 0)
|
||||
return ASN1_OVERFLOW;
|
||||
else {
|
||||
if(p[1] >= 128) {
|
||||
if(len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = 0;
|
||||
}
|
||||
*size = base - p;
|
||||
return 0;
|
||||
}
|
||||
@@ -70,9 +76,10 @@ der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size)
|
||||
}
|
||||
|
||||
int
|
||||
der_put_int (unsigned char *p, size_t len, int val, size_t *size)
|
||||
der_put_integer (unsigned char *p, size_t len, const int *v, size_t *size)
|
||||
{
|
||||
unsigned char *base = p;
|
||||
int val = *v;
|
||||
|
||||
if(val >= 0) {
|
||||
do {
|
||||
@@ -114,22 +121,26 @@ der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
|
||||
{
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
|
||||
if (val < 128) {
|
||||
*p = val;
|
||||
*size = 1;
|
||||
return 0;
|
||||
} else {
|
||||
size_t l;
|
||||
int e;
|
||||
size_t l = 0;
|
||||
|
||||
e = der_put_unsigned (p, len - 1, val, &l);
|
||||
if (e)
|
||||
return e;
|
||||
p -= l;
|
||||
while(val > 0) {
|
||||
if(len < 2)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = val % 256;
|
||||
val /= 256;
|
||||
len--;
|
||||
l++;
|
||||
}
|
||||
*p = 0x80 | l;
|
||||
*size = l + 1;
|
||||
return 0;
|
||||
if(size)
|
||||
*size = l + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -160,6 +171,65 @@ der_put_general_string (unsigned char *p, size_t len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_utf8string (unsigned char *p, size_t len,
|
||||
const heim_utf8_string *str, size_t *size)
|
||||
{
|
||||
return der_put_general_string(p, len, str, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_put_printable_string (unsigned char *p, size_t len,
|
||||
const heim_printable_string *str, size_t *size)
|
||||
{
|
||||
return der_put_general_string(p, len, str, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_put_ia5_string (unsigned char *p, size_t len,
|
||||
const heim_ia5_string *str, size_t *size)
|
||||
{
|
||||
return der_put_general_string(p, len, str, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_put_bmp_string (unsigned char *p, size_t len,
|
||||
const heim_bmp_string *data, size_t *size)
|
||||
{
|
||||
size_t i;
|
||||
if (len / 2 < data->length)
|
||||
return ASN1_OVERFLOW;
|
||||
p -= data->length * 2;
|
||||
len -= data->length * 2;
|
||||
for (i = 0; i < data->length; i++) {
|
||||
p[1] = (data->data[i] >> 8) & 0xff;
|
||||
p[2] = data->data[i] & 0xff;
|
||||
p += 2;
|
||||
}
|
||||
if (size) *size = data->length * 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_universal_string (unsigned char *p, size_t len,
|
||||
const heim_universal_string *data, size_t *size)
|
||||
{
|
||||
size_t i;
|
||||
if (len / 4 < data->length)
|
||||
return ASN1_OVERFLOW;
|
||||
p -= data->length * 4;
|
||||
len -= data->length * 4;
|
||||
for (i = 0; i < data->length; i++) {
|
||||
p[1] = (data->data[i] >> 24) & 0xff;
|
||||
p[2] = (data->data[i] >> 16) & 0xff;
|
||||
p[3] = (data->data[i] >> 8) & 0xff;
|
||||
p[4] = data->data[i] & 0xff;
|
||||
p += 4;
|
||||
}
|
||||
if (size) *size = data->length * 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_octet_string (unsigned char *p, size_t len,
|
||||
const heim_octet_string *data, size_t *size)
|
||||
@@ -173,6 +243,98 @@ der_put_octet_string (unsigned char *p, size_t len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_heim_integer (unsigned char *p, size_t len,
|
||||
const heim_integer *data, size_t *size)
|
||||
{
|
||||
unsigned char *buf = data->data;
|
||||
int hibitset = 0;
|
||||
|
||||
if (data->length == 0) {
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = 0;
|
||||
if (size)
|
||||
*size = 1;
|
||||
return 0;
|
||||
}
|
||||
if (len < data->length)
|
||||
return ASN1_OVERFLOW;
|
||||
|
||||
len -= data->length;
|
||||
|
||||
if (data->negative) {
|
||||
int i, carry;
|
||||
for (i = data->length - 1, carry = 1; i >= 0; i--) {
|
||||
*p = buf[i] ^ 0xff;
|
||||
if (carry)
|
||||
carry = !++*p;
|
||||
p--;
|
||||
}
|
||||
if (p[1] < 128) {
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = 0xff;
|
||||
len--;
|
||||
hibitset = 1;
|
||||
}
|
||||
} else {
|
||||
p -= data->length;
|
||||
memcpy(p + 1, buf, data->length);
|
||||
|
||||
if (p[1] >= 128) {
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
p[0] = 0;
|
||||
len--;
|
||||
hibitset = 1;
|
||||
}
|
||||
}
|
||||
if (size)
|
||||
*size = data->length + hibitset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_generalized_time (unsigned char *p, size_t len,
|
||||
const time_t *data, size_t *size)
|
||||
{
|
||||
heim_octet_string k;
|
||||
size_t l;
|
||||
int e;
|
||||
|
||||
e = _heim_time2generalizedtime (*data, &k, 1);
|
||||
if (e)
|
||||
return e;
|
||||
e = der_put_octet_string(p, len, &k, &l);
|
||||
free(k.data);
|
||||
if(e)
|
||||
return e;
|
||||
if(size)
|
||||
*size = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_utctime (unsigned char *p, size_t len,
|
||||
const time_t *data, size_t *size)
|
||||
{
|
||||
heim_octet_string k;
|
||||
size_t l;
|
||||
int e;
|
||||
|
||||
e = _heim_time2generalizedtime (*data, &k, 0);
|
||||
if (e)
|
||||
return e;
|
||||
e = der_put_octet_string(p, len, &k, &l);
|
||||
free(k.data);
|
||||
if(e)
|
||||
return e;
|
||||
if(size)
|
||||
*size = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_oid (unsigned char *p, size_t len,
|
||||
const heim_oid *data, size_t *size)
|
||||
@@ -205,18 +367,39 @@ der_put_oid (unsigned char *p, size_t len,
|
||||
|
||||
int
|
||||
der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
|
||||
int tag, size_t *size)
|
||||
unsigned int tag, size_t *size)
|
||||
{
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p = (class << 6) | (type << 5) | tag; /* XXX */
|
||||
*size = 1;
|
||||
if (tag <= 30) {
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p = MAKE_TAG(class, type, tag);
|
||||
*size = 1;
|
||||
} else {
|
||||
size_t ret = 0;
|
||||
unsigned int continuation = 0;
|
||||
|
||||
do {
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = tag % 128 | continuation;
|
||||
len--;
|
||||
ret++;
|
||||
tag /= 128;
|
||||
continuation = 0x80;
|
||||
} while(tag > 0);
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = MAKE_TAG(class, type, 0x1f);
|
||||
ret++;
|
||||
*size = ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
|
||||
Der_class class, Der_type type, int tag, size_t *size)
|
||||
Der_class class, Der_type type,
|
||||
unsigned int tag, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t l;
|
||||
@@ -239,229 +422,55 @@ der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
|
||||
}
|
||||
|
||||
int
|
||||
encode_boolean (unsigned char *p, size_t len, const int *data,
|
||||
size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t l;
|
||||
int e;
|
||||
|
||||
e = der_put_boolean (p, len, data, &l);
|
||||
if(e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_Boolean, &l);
|
||||
if (e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
*size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
encode_integer (unsigned char *p, size_t len, const int *data, size_t *size)
|
||||
{
|
||||
int num = *data;
|
||||
size_t ret = 0;
|
||||
size_t l;
|
||||
int e;
|
||||
|
||||
e = der_put_int (p, len, num, &l);
|
||||
if(e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_Integer, &l);
|
||||
if (e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
*size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
encode_unsigned (unsigned char *p, size_t len, const unsigned *data,
|
||||
size_t *size)
|
||||
{
|
||||
unsigned num = *data;
|
||||
size_t ret = 0;
|
||||
size_t l;
|
||||
int e;
|
||||
|
||||
e = der_put_unsigned (p, len, num, &l);
|
||||
if(e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
/* if first octet has msb set, we need to pad with a zero byte */
|
||||
if(p[1] >= 128) {
|
||||
if(len == 0)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = 0;
|
||||
len--;
|
||||
ret++;
|
||||
l++;
|
||||
}
|
||||
e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_Integer, &l);
|
||||
if (e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
*size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
encode_enumerated (unsigned char *p, size_t len, const unsigned *data,
|
||||
size_t *size)
|
||||
{
|
||||
unsigned num = *data;
|
||||
size_t ret = 0;
|
||||
size_t l;
|
||||
int e;
|
||||
|
||||
e = der_put_int (p, len, num, &l);
|
||||
if(e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_Enumerated, &l);
|
||||
if (e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
*size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
encode_general_string (unsigned char *p, size_t len,
|
||||
const heim_general_string *data, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t l;
|
||||
int e;
|
||||
|
||||
e = der_put_general_string (p, len, data, &l);
|
||||
if (e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_GeneralString, &l);
|
||||
if (e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
*size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
encode_octet_string (unsigned char *p, size_t len,
|
||||
const heim_octet_string *k, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t l;
|
||||
int e;
|
||||
|
||||
e = der_put_octet_string (p, len, k, &l);
|
||||
if (e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_OctetString, &l);
|
||||
if (e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
*size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
encode_oid(unsigned char *p, size_t len,
|
||||
const heim_oid *k, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t l;
|
||||
int e;
|
||||
|
||||
e = der_put_oid (p, len, k, &l);
|
||||
if (e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_OID, &l);
|
||||
if (e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
*size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
time2generalizedtime (time_t t, heim_octet_string *s)
|
||||
_heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep)
|
||||
{
|
||||
struct tm *tm;
|
||||
size_t len;
|
||||
|
||||
len = 15;
|
||||
const size_t len = gtimep ? 15 : 13;
|
||||
|
||||
s->data = malloc(len + 1);
|
||||
if (s->data == NULL)
|
||||
return ENOMEM;
|
||||
s->length = len;
|
||||
tm = gmtime (&t);
|
||||
snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
if (gtimep)
|
||||
snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
else
|
||||
snprintf (s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ",
|
||||
tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
encode_generalized_time (unsigned char *p, size_t len,
|
||||
const time_t *t, size_t *size)
|
||||
der_put_bit_string (unsigned char *p, size_t len,
|
||||
const heim_bit_string *data, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t l;
|
||||
heim_octet_string k;
|
||||
int e;
|
||||
|
||||
e = time2generalizedtime (*t, &k);
|
||||
if (e)
|
||||
return e;
|
||||
e = der_put_octet_string (p, len, &k, &l);
|
||||
free (k.data);
|
||||
if (e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
e = der_put_length_and_tag (p, len, k.length, ASN1_C_UNIV, PRIM,
|
||||
UT_GeneralizedTime, &l);
|
||||
if (e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
*size = ret;
|
||||
size_t data_size = (data->length + 7) / 8;
|
||||
if (len < data_size + 1)
|
||||
return ASN1_OVERFLOW;
|
||||
p -= data_size + 1;
|
||||
len -= data_size + 1;
|
||||
memcpy (p+2, data->data, data_size);
|
||||
if (data->length && (data->length % 8) != 0)
|
||||
p[1] = 8 - (data->length % 8);
|
||||
else
|
||||
p[1] = 0;
|
||||
*size = data_size + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_heim_der_set_sort(const void *a1, const void *a2)
|
||||
{
|
||||
const struct heim_octet_string *s1 = a1, *s2 = a2;
|
||||
int ret;
|
||||
|
||||
ret = memcmp(s1->data, s2->data,
|
||||
s1->length < s2->length ? s1->length : s2->length);
|
||||
if(ret)
|
||||
return ret;
|
||||
return s1->length - s2->length;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 2003 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -103,7 +103,7 @@ int
|
||||
copy_heim_any(const heim_any *from, heim_any *to)
|
||||
{
|
||||
to->data = malloc(from->length);
|
||||
if (to->data == NULL)
|
||||
if (to->data == NULL && from->length != 0)
|
||||
return ENOMEM;
|
||||
memcpy(to->data, from->data, from->length);
|
||||
to->length = from->length;
|
||||
@@ -124,7 +124,7 @@ decode_heim_any_set(const unsigned char *p, size_t len,
|
||||
{
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->data = malloc(len);
|
||||
if (data->data == NULL)
|
||||
if (data->data == NULL && len != 0)
|
||||
return ENOMEM;
|
||||
data->length = len;
|
||||
memcpy(data->data, p, len);
|
||||
@@ -149,3 +149,11 @@ copy_heim_any_set(const heim_any_set *from, heim_any_set *to)
|
||||
{
|
||||
return copy_heim_any(from, to);
|
||||
}
|
||||
|
||||
int
|
||||
heim_any_cmp(const heim_any_set *p, const heim_any_set *q)
|
||||
{
|
||||
if (p->length != q->length)
|
||||
return p->length - q->length;
|
||||
return memcmp(p->data, q->data, p->length);
|
||||
}
|
||||
|
930
lib/asn1/gen.c
930
lib/asn1/gen.c
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2000 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -35,123 +35,212 @@
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
static int used_fail;
|
||||
|
||||
static void
|
||||
copy_primitive (const char *typename, const char *from, const char *to)
|
||||
{
|
||||
fprintf (codefile, "if(copy_%s(%s, %s)) return ENOMEM;\n",
|
||||
fprintf (codefile, "if(copy_%s(%s, %s)) goto fail;\n",
|
||||
typename, from, to);
|
||||
used_fail++;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_type (const char *from, const char *to, const Type *t)
|
||||
copy_type (const char *from, const char *to, const Type *t, int preserve)
|
||||
{
|
||||
switch (t->type) {
|
||||
case TType:
|
||||
switch (t->type) {
|
||||
case TType:
|
||||
#if 0
|
||||
copy_type (from, to, t->symbol->type);
|
||||
copy_type (from, to, t->symbol->type, preserve);
|
||||
#endif
|
||||
fprintf (codefile, "if(copy_%s(%s, %s)) return ENOMEM;\n",
|
||||
t->symbol->gen_name, from, to);
|
||||
break;
|
||||
case TInteger:
|
||||
case TUInteger:
|
||||
case TBoolean:
|
||||
case TEnumerated :
|
||||
fprintf(codefile, "*(%s) = *(%s);\n", to, from);
|
||||
break;
|
||||
case TOctetString:
|
||||
copy_primitive ("octet_string", from, to);
|
||||
break;
|
||||
case TOID:
|
||||
copy_primitive ("oid", from, to);
|
||||
break;
|
||||
case TBitString: {
|
||||
fprintf(codefile, "*(%s) = *(%s);\n", to, from);
|
||||
break;
|
||||
}
|
||||
case TSequence: {
|
||||
Member *m;
|
||||
int tag = -1;
|
||||
fprintf (codefile, "if(copy_%s(%s, %s)) goto fail;\n",
|
||||
t->symbol->gen_name, from, to);
|
||||
used_fail++;
|
||||
break;
|
||||
case TInteger:
|
||||
if (t->range == NULL && t->members == NULL) {
|
||||
copy_primitive ("heim_integer", from, to);
|
||||
break;
|
||||
}
|
||||
case TBoolean:
|
||||
case TEnumerated :
|
||||
fprintf(codefile, "*(%s) = *(%s);\n", to, from);
|
||||
break;
|
||||
case TOctetString:
|
||||
copy_primitive ("octet_string", from, to);
|
||||
break;
|
||||
case TBitString:
|
||||
if (ASN1_TAILQ_EMPTY(t->members))
|
||||
copy_primitive ("bit_string", from, to);
|
||||
else
|
||||
fprintf(codefile, "*(%s) = *(%s);\n", to, from);
|
||||
break;
|
||||
case TSet:
|
||||
case TSequence:
|
||||
case TChoice: {
|
||||
Member *m, *have_ellipsis = NULL;
|
||||
|
||||
if (t->members == NULL)
|
||||
break;
|
||||
if(t->members == NULL)
|
||||
break;
|
||||
|
||||
for (m = t->members; m && tag != m->val; m = m->next) {
|
||||
char *fn;
|
||||
char *tn;
|
||||
if ((t->type == TSequence || t->type == TChoice) && preserve) {
|
||||
fprintf(codefile,
|
||||
"{ int ret;\n"
|
||||
"ret = copy_octet_string(&(%s)->_save, &(%s)->_save);\n"
|
||||
"if (ret) goto fail;\n"
|
||||
"}\n",
|
||||
from, to);
|
||||
used_fail++;
|
||||
}
|
||||
|
||||
asprintf (&fn, "%s(%s)->%s",
|
||||
m->optional ? "" : "&", from, m->gen_name);
|
||||
asprintf (&tn, "%s(%s)->%s",
|
||||
m->optional ? "" : "&", to, m->gen_name);
|
||||
if(m->optional){
|
||||
fprintf(codefile, "if(%s) {\n", fn);
|
||||
fprintf(codefile, "%s = malloc(sizeof(*%s));\n", tn, tn);
|
||||
fprintf(codefile, "if(%s == NULL) return ENOMEM;\n", tn);
|
||||
}
|
||||
copy_type (fn, tn, m->type);
|
||||
if(m->optional){
|
||||
fprintf(codefile, "}else\n");
|
||||
fprintf(codefile, "%s = NULL;\n", tn);
|
||||
}
|
||||
if (tag == -1)
|
||||
tag = m->val;
|
||||
free (fn);
|
||||
free (tn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSequenceOf: {
|
||||
char *f;
|
||||
char *T;
|
||||
if(t->type == TChoice) {
|
||||
fprintf(codefile, "(%s)->element = (%s)->element;\n", to, from);
|
||||
fprintf(codefile, "switch((%s)->element) {\n", from);
|
||||
}
|
||||
|
||||
fprintf (codefile, "if(((%s)->val = "
|
||||
"malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n",
|
||||
to, from, to, from);
|
||||
fprintf (codefile, "return ENOMEM;\n");
|
||||
fprintf(codefile,
|
||||
"for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n",
|
||||
to, to, from, to);
|
||||
asprintf(&f, "&(%s)->val[(%s)->len]", from, to);
|
||||
asprintf(&T, "&(%s)->val[(%s)->len]", to, to);
|
||||
copy_type(f, T, t->subtype);
|
||||
fprintf(codefile, "}\n");
|
||||
free(f);
|
||||
free(T);
|
||||
break;
|
||||
}
|
||||
case TGeneralizedTime:
|
||||
fprintf(codefile, "*(%s) = *(%s);\n", to, from);
|
||||
break;
|
||||
case TGeneralString:
|
||||
copy_primitive ("general_string", from, to);
|
||||
break;
|
||||
case TUTF8String:
|
||||
copy_primitive ("utf8string", from, to);
|
||||
break;
|
||||
case TNull:
|
||||
break;
|
||||
case TApplication:
|
||||
copy_type (from, to, t->subtype);
|
||||
break;
|
||||
default :
|
||||
abort ();
|
||||
}
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *fs;
|
||||
char *ts;
|
||||
|
||||
if (m->ellipsis) {
|
||||
have_ellipsis = m;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(t->type == TChoice)
|
||||
fprintf(codefile, "case %s:\n", m->label);
|
||||
|
||||
asprintf (&fs, "%s(%s)->%s%s",
|
||||
m->optional ? "" : "&", from,
|
||||
t->type == TChoice ? "u." : "", m->gen_name);
|
||||
if (fs == NULL)
|
||||
errx(1, "malloc");
|
||||
asprintf (&ts, "%s(%s)->%s%s",
|
||||
m->optional ? "" : "&", to,
|
||||
t->type == TChoice ? "u." : "", m->gen_name);
|
||||
if (ts == NULL)
|
||||
errx(1, "malloc");
|
||||
if(m->optional){
|
||||
fprintf(codefile, "if(%s) {\n", fs);
|
||||
fprintf(codefile, "%s = malloc(sizeof(*%s));\n", ts, ts);
|
||||
fprintf(codefile, "if(%s == NULL) goto fail;\n", ts);
|
||||
used_fail++;
|
||||
}
|
||||
copy_type (fs, ts, m->type, FALSE);
|
||||
if(m->optional){
|
||||
fprintf(codefile, "}else\n");
|
||||
fprintf(codefile, "%s = NULL;\n", ts);
|
||||
}
|
||||
free (fs);
|
||||
free (ts);
|
||||
if(t->type == TChoice)
|
||||
fprintf(codefile, "break;\n");
|
||||
}
|
||||
if(t->type == TChoice) {
|
||||
if (have_ellipsis) {
|
||||
fprintf(codefile, "case %s: {\n"
|
||||
"int ret;\n"
|
||||
"ret = copy_octet_string(&(%s)->u.%s, &(%s)->u.%s);\n"
|
||||
"if (ret) goto fail;\n"
|
||||
"break;\n"
|
||||
"}\n",
|
||||
have_ellipsis->label,
|
||||
from, have_ellipsis->gen_name,
|
||||
to, have_ellipsis->gen_name);
|
||||
used_fail++;
|
||||
}
|
||||
fprintf(codefile, "}\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSetOf:
|
||||
case TSequenceOf: {
|
||||
char *f;
|
||||
char *T;
|
||||
|
||||
fprintf (codefile, "if(((%s)->val = "
|
||||
"malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n",
|
||||
to, from, to, from);
|
||||
fprintf (codefile, "goto fail;\n");
|
||||
used_fail++;
|
||||
fprintf(codefile,
|
||||
"for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n",
|
||||
to, to, from, to);
|
||||
asprintf(&f, "&(%s)->val[(%s)->len]", from, to);
|
||||
if (f == NULL)
|
||||
errx(1, "malloc");
|
||||
asprintf(&T, "&(%s)->val[(%s)->len]", to, to);
|
||||
if (T == NULL)
|
||||
errx(1, "malloc");
|
||||
copy_type(f, T, t->subtype, FALSE);
|
||||
fprintf(codefile, "}\n");
|
||||
free(f);
|
||||
free(T);
|
||||
break;
|
||||
}
|
||||
case TGeneralizedTime:
|
||||
fprintf(codefile, "*(%s) = *(%s);\n", to, from);
|
||||
break;
|
||||
case TGeneralString:
|
||||
copy_primitive ("general_string", from, to);
|
||||
break;
|
||||
case TUTCTime:
|
||||
fprintf(codefile, "*(%s) = *(%s);\n", to, from);
|
||||
break;
|
||||
case TUTF8String:
|
||||
copy_primitive ("utf8string", from, to);
|
||||
break;
|
||||
case TPrintableString:
|
||||
copy_primitive ("printable_string", from, to);
|
||||
break;
|
||||
case TIA5String:
|
||||
copy_primitive ("ia5_string", from, to);
|
||||
break;
|
||||
case TBMPString:
|
||||
copy_primitive ("bmp_string", from, to);
|
||||
break;
|
||||
case TUniversalString:
|
||||
copy_primitive ("universal_string", from, to);
|
||||
break;
|
||||
case TTag:
|
||||
copy_type (from, to, t->subtype, preserve);
|
||||
break;
|
||||
case TOID:
|
||||
copy_primitive ("oid", from, to);
|
||||
break;
|
||||
case TNull:
|
||||
break;
|
||||
default :
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
generate_type_copy (const Symbol *s)
|
||||
{
|
||||
int preserve = preserve_type(s->name) ? TRUE : FALSE;
|
||||
|
||||
used_fail = 0;
|
||||
|
||||
fprintf (headerfile,
|
||||
"int copy_%s (const %s *, %s *);\n",
|
||||
s->gen_name, s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile, "int\n"
|
||||
"copy_%s(const %s *from, %s *to)\n"
|
||||
"{\n",
|
||||
"{\n"
|
||||
"memset(to, 0, sizeof(*to));\n",
|
||||
s->gen_name, s->gen_name, s->gen_name);
|
||||
copy_type ("from", "to", s->type, preserve);
|
||||
fprintf (codefile, "return 0;\n");
|
||||
|
||||
copy_type ("from", "to", s->type);
|
||||
fprintf (codefile, "return 0;\n}\n\n");
|
||||
if (used_fail)
|
||||
fprintf (codefile, "fail:\n"
|
||||
"free_%s(to);\n"
|
||||
"return ENOMEM;\n",
|
||||
s->gen_name);
|
||||
|
||||
fprintf(codefile,
|
||||
"}\n\n");
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2001 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -36,284 +36,538 @@
|
||||
RCSID("$Id$");
|
||||
|
||||
static void
|
||||
decode_primitive (const char *typename, const char *name)
|
||||
decode_primitive (const char *typename, const char *name, const char *forwstr)
|
||||
{
|
||||
#if 0
|
||||
fprintf (codefile,
|
||||
"e = decode_%s(p, len, %s, &l);\n"
|
||||
"FORW;\n",
|
||||
"%s;\n",
|
||||
typename,
|
||||
name);
|
||||
name,
|
||||
forwstr);
|
||||
#else
|
||||
fprintf (codefile,
|
||||
"e = der_get_%s(p, len, %s, &l);\n"
|
||||
"if(e) %s;\np += l; len -= l; ret += l;\n",
|
||||
typename,
|
||||
name,
|
||||
forwstr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
is_primitive_type(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case TInteger:
|
||||
case TBoolean:
|
||||
case TOctetString:
|
||||
case TBitString:
|
||||
case TEnumerated:
|
||||
case TGeneralizedTime:
|
||||
case TGeneralString:
|
||||
case TOID:
|
||||
case TUTCTime:
|
||||
case TUTF8String:
|
||||
case TPrintableString:
|
||||
case TIA5String:
|
||||
case TBMPString:
|
||||
case TUniversalString:
|
||||
case TNull:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
decode_type (const char *name, const Type *t)
|
||||
find_tag (const Type *t,
|
||||
Der_class *cl, Der_type *ty, unsigned *tag)
|
||||
{
|
||||
switch (t->type) {
|
||||
case TType:
|
||||
#if 0
|
||||
decode_type (name, t->symbol->type);
|
||||
#endif
|
||||
fprintf (codefile,
|
||||
"e = decode_%s(p, len, %s, &l);\n"
|
||||
"FORW;\n",
|
||||
t->symbol->gen_name, name);
|
||||
case TBitString:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_BitString;
|
||||
break;
|
||||
case TBoolean:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_Boolean;
|
||||
break;
|
||||
case TChoice:
|
||||
errx(1, "Cannot have recursive CHOICE");
|
||||
case TEnumerated:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_Enumerated;
|
||||
break;
|
||||
case TGeneralString:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_GeneralString;
|
||||
break;
|
||||
case TGeneralizedTime:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_GeneralizedTime;
|
||||
break;
|
||||
case TIA5String:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_IA5String;
|
||||
break;
|
||||
case TInteger:
|
||||
if(t->members == NULL)
|
||||
decode_primitive ("integer", name);
|
||||
else {
|
||||
char *s;
|
||||
asprintf(&s, "(int*)%s", name);
|
||||
if(s == NULL)
|
||||
errx (1, "out of memory");
|
||||
decode_primitive ("integer", s);
|
||||
free(s);
|
||||
}
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_Integer;
|
||||
break;
|
||||
case TUInteger:
|
||||
decode_primitive ("unsigned", name);
|
||||
case TNull:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_Null;
|
||||
break;
|
||||
case TEnumerated:
|
||||
decode_primitive ("enumerated", name);
|
||||
case TOID:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_OID;
|
||||
break;
|
||||
case TOctetString:
|
||||
decode_primitive ("octet_string", name);
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_OctetString;
|
||||
break;
|
||||
case TOID :
|
||||
decode_primitive ("oid", name);
|
||||
case TPrintableString:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_PrintableString;
|
||||
break;
|
||||
case TSequence:
|
||||
case TSequenceOf:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = CONS;
|
||||
*tag = UT_Sequence;
|
||||
break;
|
||||
case TSet:
|
||||
case TSetOf:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = CONS;
|
||||
*tag = UT_Set;
|
||||
break;
|
||||
case TTag:
|
||||
*cl = t->tag.tagclass;
|
||||
*ty = is_primitive_type(t->subtype->type) ? PRIM : CONS;
|
||||
*tag = t->tag.tagvalue;
|
||||
break;
|
||||
case TType:
|
||||
return find_tag(t->symbol->type, cl, ty, tag);
|
||||
case TUTCTime:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_UTCTime;
|
||||
break;
|
||||
case TUTF8String:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_UTF8String;
|
||||
break;
|
||||
case TBMPString:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_BMPString;
|
||||
break;
|
||||
case TUniversalString:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_UniversalString;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
decode_type (const char *name, const Type *t, int optional,
|
||||
const char *forwstr)
|
||||
{
|
||||
switch (t->type) {
|
||||
case TType: {
|
||||
if (optional)
|
||||
fprintf(codefile,
|
||||
"%s = calloc(1, sizeof(*%s));\n"
|
||||
"if (%s == NULL) %s;\n",
|
||||
name, name, name, forwstr);
|
||||
fprintf (codefile,
|
||||
"e = decode_%s(p, len, %s, &l);\n",
|
||||
t->symbol->gen_name, name);
|
||||
if (optional) {
|
||||
fprintf (codefile,
|
||||
"if(e) {\n"
|
||||
"free(%s);\n"
|
||||
"%s = NULL;\n"
|
||||
"} else {\n"
|
||||
"p += l; len -= l; ret += l;\n"
|
||||
"}\n",
|
||||
name, name);
|
||||
} else {
|
||||
fprintf (codefile,
|
||||
"if(e) %s;\n",
|
||||
forwstr);
|
||||
fprintf (codefile,
|
||||
"p += l; len -= l; ret += l;\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TInteger:
|
||||
if(t->members) {
|
||||
char *s;
|
||||
asprintf(&s, "(int*)%s", name);
|
||||
if (s == NULL)
|
||||
errx (1, "out of memory");
|
||||
decode_primitive ("integer", s, forwstr);
|
||||
free(s);
|
||||
} else if (t->range == NULL) {
|
||||
decode_primitive ("heim_integer", name, forwstr);
|
||||
} else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
|
||||
decode_primitive ("integer", name, forwstr);
|
||||
} else if (t->range->min == 0 && t->range->max == UINT_MAX) {
|
||||
decode_primitive ("unsigned", name, forwstr);
|
||||
} else if (t->range->min == 0 && t->range->max == INT_MAX) {
|
||||
decode_primitive ("unsigned", name, forwstr);
|
||||
} else
|
||||
errx(1, "%s: unsupported range %d -> %d",
|
||||
name, t->range->min, t->range->max);
|
||||
break;
|
||||
case TBoolean:
|
||||
decode_primitive ("boolean", name, forwstr);
|
||||
break;
|
||||
case TEnumerated:
|
||||
decode_primitive ("enumerated", name, forwstr);
|
||||
break;
|
||||
case TOctetString:
|
||||
decode_primitive ("octet_string", name, forwstr);
|
||||
break;
|
||||
case TBitString: {
|
||||
Member *m;
|
||||
int tag = -1;
|
||||
int pos;
|
||||
int pos = 0;
|
||||
|
||||
fprintf (codefile,
|
||||
"e = der_match_tag_and_length (p, len, ASN1_C_UNIV, PRIM, UT_BitString,"
|
||||
"&reallen, &l);\n"
|
||||
"FORW;\n"
|
||||
"if(len < reallen)\n"
|
||||
"return ASN1_OVERRUN;\n"
|
||||
"p++;\n"
|
||||
"len--;\n"
|
||||
"reallen--;\n"
|
||||
"ret++;\n");
|
||||
pos = 0;
|
||||
for (m = t->members; m && tag != m->val; m = m->next) {
|
||||
if (ASN1_TAILQ_EMPTY(t->members)) {
|
||||
decode_primitive ("bit_string", name, forwstr);
|
||||
break;
|
||||
}
|
||||
fprintf(codefile,
|
||||
"if (len < 1) return ASN1_OVERRUN;\n"
|
||||
"p++; len--; ret++;\n");
|
||||
fprintf(codefile,
|
||||
"do {\n"
|
||||
"if (len < 1) break;\n");
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
while (m->val / 8 > pos / 8) {
|
||||
fprintf (codefile,
|
||||
"p++; len--; reallen--; ret++;\n");
|
||||
"p++; len--; ret++;\n"
|
||||
"if (len < 1) break;\n");
|
||||
pos += 8;
|
||||
}
|
||||
fprintf (codefile,
|
||||
"%s->%s = (*p >> %d) & 1;\n",
|
||||
"(%s)->%s = (*p >> %d) & 1;\n",
|
||||
name, m->gen_name, 7 - m->val % 8);
|
||||
if (tag == -1)
|
||||
tag = m->val;
|
||||
}
|
||||
fprintf(codefile,
|
||||
"} while(0);\n");
|
||||
fprintf (codefile,
|
||||
"p += reallen; len -= reallen; ret += reallen;\n");
|
||||
"p += len; ret += len;\n");
|
||||
break;
|
||||
}
|
||||
case TSequence: {
|
||||
Member *m;
|
||||
int tag = -1;
|
||||
int fd_counter = unique_get_next();
|
||||
int fd_counter_inner = unique_get_next();
|
||||
|
||||
if (t->members == NULL)
|
||||
break;
|
||||
|
||||
fprintf (codefile,
|
||||
"e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,"
|
||||
"&reallen, &l);\n"
|
||||
"FORW;\n"
|
||||
"{\n"
|
||||
"int dce_fix%d;\n"
|
||||
"if((dce_fix%d = fix_dce(reallen, &len)) < 0)\n"
|
||||
"return ASN1_BAD_FORMAT;\n",
|
||||
fd_counter, fd_counter);
|
||||
|
||||
for (m = t->members; m && tag != m->val; m = m->next) {
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *s;
|
||||
|
||||
asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
|
||||
if (0 && m->type->type == TType){
|
||||
if(m->optional)
|
||||
fprintf (codefile,
|
||||
"%s = malloc(sizeof(*%s));\n"
|
||||
"if(%s == NULL) return ENOMEM;\n", s, s, s);
|
||||
fprintf (codefile,
|
||||
"e = decode_seq_%s(p, len, %d, %d, %s, &l);\n",
|
||||
m->type->symbol->gen_name,
|
||||
m->val,
|
||||
m->optional,
|
||||
s);
|
||||
if(m->optional)
|
||||
fprintf (codefile,
|
||||
"if (e == ASN1_MISSING_FIELD) {\n"
|
||||
"free(%s);\n"
|
||||
"%s = NULL;\n"
|
||||
"e = l = 0;\n"
|
||||
"}\n",
|
||||
s, s);
|
||||
if (m->ellipsis)
|
||||
continue;
|
||||
|
||||
fprintf (codefile, "FORW;\n");
|
||||
|
||||
}else{
|
||||
fprintf (codefile, "{\n"
|
||||
"size_t newlen, oldlen;\n\n"
|
||||
"e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, %d, &l);\n",
|
||||
m->val);
|
||||
fprintf (codefile,
|
||||
"if (e)\n");
|
||||
if(m->optional)
|
||||
/* XXX should look at e */
|
||||
fprintf (codefile,
|
||||
"%s = NULL;\n", s);
|
||||
else
|
||||
fprintf (codefile,
|
||||
"return e;\n");
|
||||
fprintf (codefile,
|
||||
"else {\n");
|
||||
fprintf (codefile,
|
||||
"p += l;\n"
|
||||
"len -= l;\n"
|
||||
"ret += l;\n"
|
||||
"e = der_get_length (p, len, &newlen, &l);\n"
|
||||
"FORW;\n"
|
||||
"{\n"
|
||||
|
||||
"int dce_fix%d;\n"
|
||||
"oldlen = len;\n"
|
||||
"if((dce_fix%d = fix_dce(newlen, &len)) < 0)"
|
||||
"return ASN1_BAD_FORMAT;\n",
|
||||
fd_counter_inner,
|
||||
fd_counter_inner);
|
||||
if (m->optional)
|
||||
fprintf (codefile,
|
||||
"%s = malloc(sizeof(*%s));\n"
|
||||
"if(%s == NULL) return ENOMEM;\n", s, s, s);
|
||||
decode_type (s, m->type);
|
||||
fprintf (codefile,
|
||||
"if(dce_fix%d){\n"
|
||||
"e = der_match_tag_and_length (p, len, "
|
||||
"(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
|
||||
"FORW;\n"
|
||||
"}else \n"
|
||||
"len = oldlen - newlen;\n"
|
||||
"}\n"
|
||||
"}\n",
|
||||
fd_counter_inner);
|
||||
fprintf (codefile,
|
||||
"}\n");
|
||||
}
|
||||
if (tag == -1)
|
||||
tag = m->val;
|
||||
asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&",
|
||||
name, m->gen_name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
decode_type (s, m->type, m->optional, forwstr);
|
||||
free (s);
|
||||
}
|
||||
fprintf(codefile,
|
||||
"if(dce_fix%d){\n"
|
||||
"e = der_match_tag_and_length (p, len, "
|
||||
"(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
|
||||
"FORW;\n"
|
||||
"}\n"
|
||||
"}\n",
|
||||
fd_counter);
|
||||
|
||||
break;
|
||||
}
|
||||
case TSet: {
|
||||
Member *m;
|
||||
unsigned int memno;
|
||||
|
||||
if(t->members == NULL)
|
||||
break;
|
||||
|
||||
fprintf(codefile, "{\n");
|
||||
fprintf(codefile, "unsigned int members = 0;\n");
|
||||
fprintf(codefile, "while(len > 0) {\n");
|
||||
fprintf(codefile,
|
||||
"Der_class class;\n"
|
||||
"Der_type type;\n"
|
||||
"int tag;\n"
|
||||
"e = der_get_tag (p, len, &class, &type, &tag, NULL);\n"
|
||||
"if(e) %s;\n", forwstr);
|
||||
fprintf(codefile, "switch (MAKE_TAG(class, type, tag)) {\n");
|
||||
memno = 0;
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *s;
|
||||
|
||||
assert(m->type->type == TTag);
|
||||
|
||||
fprintf(codefile, "case MAKE_TAG(%s, %s, %s):\n",
|
||||
classname(m->type->tag.tagclass),
|
||||
is_primitive_type(m->type->subtype->type) ? "PRIM" : "CONS",
|
||||
valuename(m->type->tag.tagclass, m->type->tag.tagvalue));
|
||||
|
||||
asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
if(m->optional)
|
||||
fprintf(codefile,
|
||||
"%s = calloc(1, sizeof(*%s));\n"
|
||||
"if (%s == NULL) { e = ENOMEM; %s; }\n",
|
||||
s, s, s, forwstr);
|
||||
decode_type (s, m->type, 0, forwstr);
|
||||
free (s);
|
||||
|
||||
fprintf(codefile, "members |= (1 << %d);\n", memno);
|
||||
memno++;
|
||||
fprintf(codefile, "break;\n");
|
||||
}
|
||||
fprintf(codefile,
|
||||
"default:\n"
|
||||
"return ASN1_MISPLACED_FIELD;\n"
|
||||
"break;\n");
|
||||
fprintf(codefile, "}\n");
|
||||
fprintf(codefile, "}\n");
|
||||
memno = 0;
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *s;
|
||||
|
||||
asprintf (&s, "%s->%s", name, m->gen_name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
fprintf(codefile, "if((members & (1 << %d)) == 0)\n", memno);
|
||||
if(m->optional)
|
||||
fprintf(codefile, "%s = NULL;\n", s);
|
||||
else if(m->defval)
|
||||
gen_assign_defval(s, m->defval);
|
||||
else
|
||||
fprintf(codefile, "return ASN1_MISSING_FIELD;\n");
|
||||
free(s);
|
||||
memno++;
|
||||
}
|
||||
fprintf(codefile, "}\n");
|
||||
break;
|
||||
}
|
||||
case TSetOf:
|
||||
case TSequenceOf: {
|
||||
char *n;
|
||||
int oldret_counter = unique_get_next();
|
||||
|
||||
fprintf (codefile,
|
||||
"e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,"
|
||||
"&reallen, &l);\n"
|
||||
"FORW;\n"
|
||||
"if(len < reallen)\n"
|
||||
"return ASN1_OVERRUN;\n"
|
||||
"len = reallen;\n");
|
||||
|
||||
fprintf (codefile,
|
||||
"{\n"
|
||||
"size_t origlen = len;\n"
|
||||
"int oldret%d = ret;\n"
|
||||
"size_t oldret = ret;\n"
|
||||
"void *tmp;\n"
|
||||
"ret = 0;\n"
|
||||
"(%s)->len = 0;\n"
|
||||
"(%s)->val = NULL;\n"
|
||||
"while(ret < origlen) {\n"
|
||||
"tmp = realloc((%s)->val, "
|
||||
" sizeof(*((%s)->val)) * ((%s)->len + 1));\n"
|
||||
"if (tmp == NULL) { %s; }\n"
|
||||
"(%s)->len++;\n"
|
||||
"(%s)->val = realloc((%s)->val, sizeof(*((%s)->val)) * (%s)->len);\n",
|
||||
oldret_counter, name, name, name, name, name, name, name);
|
||||
"(%s)->val = tmp;\n",
|
||||
name, name, name, name, name, forwstr, name, name);
|
||||
|
||||
asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name);
|
||||
decode_type (n, t->subtype);
|
||||
if (n == NULL)
|
||||
errx(1, "malloc");
|
||||
decode_type (n, t->subtype, 0, forwstr);
|
||||
fprintf (codefile,
|
||||
"len = origlen - ret;\n"
|
||||
"}\n"
|
||||
"ret += oldret%d;\n"
|
||||
"}\n",
|
||||
oldret_counter);
|
||||
"ret += oldret;\n"
|
||||
"}\n");
|
||||
free (n);
|
||||
break;
|
||||
}
|
||||
case TGeneralizedTime:
|
||||
decode_primitive ("generalized_time", name);
|
||||
decode_primitive ("generalized_time", name, forwstr);
|
||||
break;
|
||||
case TGeneralString:
|
||||
decode_primitive ("general_string", name);
|
||||
decode_primitive ("general_string", name, forwstr);
|
||||
break;
|
||||
case TTag:{
|
||||
fprintf(codefile,
|
||||
"{\n"
|
||||
"int tagdatalen;\n"
|
||||
"size_t oldlen;\n");
|
||||
if(dce_fix)
|
||||
fprintf(codefile,
|
||||
"int dce_fix;\n");
|
||||
fprintf(codefile, "e = der_match_tag_and_length(p, len, %s, %s, %s, "
|
||||
"&tagdatalen, &l);\n",
|
||||
classname(t->tag.tagclass),
|
||||
is_primitive_type(t->subtype->type) ? "PRIM" : "CONS",
|
||||
valuename(t->tag.tagclass, t->tag.tagvalue));
|
||||
if(optional) {
|
||||
fprintf(codefile,
|
||||
"if(e) {\n"
|
||||
"%s = NULL;\n"
|
||||
"} else {\n"
|
||||
"%s = calloc(1, sizeof(*%s));\n"
|
||||
"if (%s == NULL) { e = ENOMEM; %s; }\n",
|
||||
name, name, name, name, forwstr);
|
||||
} else {
|
||||
fprintf(codefile, "if(e) %s;\n", forwstr);
|
||||
}
|
||||
fprintf (codefile,
|
||||
"p += l; len -= l; ret += l;\n"
|
||||
"oldlen = len;\n");
|
||||
if(dce_fix)
|
||||
fprintf (codefile,
|
||||
"if((dce_fix = _heim_fix_dce(tagdatalen, &len)) < 0)\n"
|
||||
"{ e = ASN1_BAD_FORMAT; %s; }\n",
|
||||
forwstr);
|
||||
else
|
||||
fprintf(codefile,
|
||||
"if (tagdatalen > len) { e = ASN1_OVERRUN; %s; }\n"
|
||||
"len = tagdatalen;\n", forwstr);
|
||||
decode_type (name, t->subtype, 0, forwstr);
|
||||
if(dce_fix)
|
||||
fprintf(codefile,
|
||||
"if(dce_fix){\n"
|
||||
"e = der_match_tag_and_length (p, len, "
|
||||
"(Der_class)0,(Der_type)0, UT_EndOfContent, "
|
||||
"&tagdatalen, &l);\n"
|
||||
"if(e) %s;\np += l; len -= l; ret += l;\n"
|
||||
"} else \n", forwstr);
|
||||
fprintf(codefile,
|
||||
"len = oldlen - tagdatalen;\n");
|
||||
if(optional)
|
||||
fprintf(codefile,
|
||||
"}\n");
|
||||
fprintf(codefile,
|
||||
"}\n");
|
||||
break;
|
||||
}
|
||||
case TChoice: {
|
||||
Member *m, *have_ellipsis = NULL;
|
||||
const char *els = "";
|
||||
|
||||
if (t->members == NULL)
|
||||
break;
|
||||
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
const Type *tt = m->type;
|
||||
char *s;
|
||||
Der_class cl;
|
||||
Der_type ty;
|
||||
unsigned tag;
|
||||
|
||||
if (m->ellipsis) {
|
||||
have_ellipsis = m;
|
||||
continue;
|
||||
}
|
||||
|
||||
find_tag(tt, &cl, &ty, &tag);
|
||||
|
||||
fprintf(codefile,
|
||||
"%sif (der_match_tag(p, len, %s, %s, %s, NULL) == 0) {\n",
|
||||
els,
|
||||
classname(cl),
|
||||
ty ? "CONS" : "PRIM",
|
||||
valuename(cl, tag));
|
||||
asprintf (&s, "%s(%s)->u.%s", m->optional ? "" : "&",
|
||||
name, m->gen_name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
decode_type (s, m->type, m->optional, forwstr);
|
||||
free(s);
|
||||
fprintf(codefile,
|
||||
"}\n");
|
||||
els = "else ";
|
||||
}
|
||||
if (have_ellipsis) {
|
||||
fprintf(codefile,
|
||||
"else {\n"
|
||||
"(%s)->u.%s.data = calloc(1, len);\n"
|
||||
"if ((%s)->u.%s.data == NULL) {\n"
|
||||
"e = ENOMEM; %s;\n"
|
||||
"}\n"
|
||||
"(%s)->u.%s.length = len;\n"
|
||||
"memcpy((%s)->u.%s.data, p, len);\n"
|
||||
"(%s)->element = %s;\n"
|
||||
"p += len;\n"
|
||||
"ret += len;\n"
|
||||
"len -= len;\n"
|
||||
"}\n",
|
||||
name, have_ellipsis->gen_name,
|
||||
name, have_ellipsis->gen_name,
|
||||
forwstr,
|
||||
name, have_ellipsis->gen_name,
|
||||
name, have_ellipsis->gen_name,
|
||||
name, have_ellipsis->label);
|
||||
} else {
|
||||
fprintf(codefile,
|
||||
"else {\n"
|
||||
"e = ASN1_PARSE_ERROR;\n"
|
||||
"%s;\n"
|
||||
"}\n",
|
||||
forwstr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TUTCTime:
|
||||
decode_primitive ("utctime", name, forwstr);
|
||||
break;
|
||||
case TUTF8String:
|
||||
decode_primitive ("utf8string", name);
|
||||
decode_primitive ("utf8string", name, forwstr);
|
||||
break;
|
||||
case TPrintableString:
|
||||
decode_primitive ("printable_string", name, forwstr);
|
||||
break;
|
||||
case TIA5String:
|
||||
decode_primitive ("ia5_string", name, forwstr);
|
||||
break;
|
||||
case TBMPString:
|
||||
decode_primitive ("bmp_string", name, forwstr);
|
||||
break;
|
||||
case TUniversalString:
|
||||
decode_primitive ("universal_string", name, forwstr);
|
||||
break;
|
||||
case TNull:
|
||||
fprintf (codefile,
|
||||
"e = decode_nulltype(p, len, &l);\n"
|
||||
"FORW;\n");
|
||||
fprintf (codefile, "/* NULL */\n");
|
||||
break;
|
||||
case TApplication:
|
||||
fprintf (codefile,
|
||||
"e = der_match_tag_and_length (p, len, ASN1_C_APPL, CONS, %d, "
|
||||
"&reallen, &l);\n"
|
||||
"FORW;\n"
|
||||
"{\n"
|
||||
"int dce_fix;\n"
|
||||
"if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
|
||||
"return ASN1_BAD_FORMAT;\n",
|
||||
t->application);
|
||||
decode_type (name, t->subtype);
|
||||
fprintf(codefile,
|
||||
"if(dce_fix){\n"
|
||||
"e = der_match_tag_and_length (p, len, "
|
||||
"(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
|
||||
"FORW;\n"
|
||||
"}\n"
|
||||
"}\n");
|
||||
|
||||
break;
|
||||
case TBoolean:
|
||||
decode_primitive ("boolean", name);
|
||||
case TOID:
|
||||
decode_primitive ("oid", name, forwstr);
|
||||
break;
|
||||
default :
|
||||
abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
generate_type_decode (const Symbol *s)
|
||||
{
|
||||
unique_reset();
|
||||
int preserve = preserve_type(s->name) ? TRUE : FALSE;
|
||||
|
||||
fprintf (headerfile,
|
||||
"int "
|
||||
"decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile, "#define FORW "
|
||||
"if(e) goto fail; "
|
||||
"p += l; "
|
||||
"len -= l; "
|
||||
"ret += l\n\n");
|
||||
|
||||
|
||||
fprintf (codefile, "int\n"
|
||||
"decode_%s(const unsigned char *p,"
|
||||
" size_t len, %s *data, size_t *size)\n"
|
||||
@@ -322,28 +576,45 @@ generate_type_decode (const Symbol *s)
|
||||
|
||||
switch (s->type->type) {
|
||||
case TInteger:
|
||||
case TUInteger:
|
||||
case TBoolean:
|
||||
case TOctetString:
|
||||
case TOID:
|
||||
case TGeneralizedTime:
|
||||
case TGeneralString:
|
||||
case TUTF8String:
|
||||
case TPrintableString:
|
||||
case TIA5String:
|
||||
case TBMPString:
|
||||
case TUniversalString:
|
||||
case TUTCTime:
|
||||
case TNull:
|
||||
case TEnumerated:
|
||||
case TBitString:
|
||||
case TSequence:
|
||||
case TSequenceOf:
|
||||
case TApplication:
|
||||
case TSet:
|
||||
case TSetOf:
|
||||
case TTag:
|
||||
case TType:
|
||||
case TChoice:
|
||||
fprintf (codefile,
|
||||
"size_t ret = 0, reallen;\n"
|
||||
"size_t l;\n"
|
||||
"int e;\n\n");
|
||||
"int e;\n");
|
||||
if (preserve)
|
||||
fprintf (codefile, "const unsigned char *begin = p;\n");
|
||||
|
||||
fprintf (codefile, "\n");
|
||||
fprintf (codefile, "memset(data, 0, sizeof(*data));\n");
|
||||
fprintf (codefile, "reallen = 0;\n"); /* hack to avoid `unused variable' */
|
||||
|
||||
decode_type ("data", s->type);
|
||||
decode_type ("data", s->type, 0, "goto fail");
|
||||
if (preserve)
|
||||
fprintf (codefile,
|
||||
"data->_save.data = calloc(1, ret);\n"
|
||||
"if (data->_save.data == NULL) { e = ENOMEM; goto fail; }\n"
|
||||
"data->_save.length = ret;\n"
|
||||
"memcpy(data->_save.data, begin, ret);\n");
|
||||
fprintf (codefile,
|
||||
"if(size) *size = ret;\n"
|
||||
"return 0;\n");
|
||||
@@ -358,62 +629,3 @@ generate_type_decode (const Symbol *s)
|
||||
}
|
||||
fprintf (codefile, "}\n\n");
|
||||
}
|
||||
|
||||
void
|
||||
generate_seq_type_decode (const Symbol *s)
|
||||
{
|
||||
fprintf (headerfile,
|
||||
"int decode_seq_%s(const unsigned char *, size_t, int, int, "
|
||||
"%s *, size_t *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile, "int\n"
|
||||
"decode_seq_%s(const unsigned char *p, size_t len, int tag, "
|
||||
"int optional, %s *data, size_t *size)\n"
|
||||
"{\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile,
|
||||
"size_t newlen, oldlen;\n"
|
||||
"size_t l, ret = 0;\n"
|
||||
"int e;\n"
|
||||
"int dce_fix;\n");
|
||||
|
||||
fprintf (codefile,
|
||||
"e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, tag, &l);\n"
|
||||
"if (e)\n"
|
||||
"return e;\n");
|
||||
fprintf (codefile,
|
||||
"p += l;\n"
|
||||
"len -= l;\n"
|
||||
"ret += l;\n"
|
||||
"e = der_get_length(p, len, &newlen, &l);\n"
|
||||
"if (e)\n"
|
||||
"return e;\n"
|
||||
"p += l;\n"
|
||||
"len -= l;\n"
|
||||
"ret += l;\n"
|
||||
"oldlen = len;\n"
|
||||
"if ((dce_fix = fix_dce(newlen, &len)) < 0)\n"
|
||||
"return ASN1_BAD_FORMAT;\n"
|
||||
"e = decode_%s(p, len, data, &l);\n"
|
||||
"if (e)\n"
|
||||
"return e;\n"
|
||||
"p += l;\n"
|
||||
"len -= l;\n"
|
||||
"ret += l;\n"
|
||||
"if (dce_fix) {\n"
|
||||
"size_t reallen;\n\n"
|
||||
"e = der_match_tag_and_length(p, len, "
|
||||
"(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
|
||||
"if (e)\n"
|
||||
"return e;\n"
|
||||
"ret += l;\n"
|
||||
"}\n",
|
||||
s->gen_name);
|
||||
fprintf (codefile,
|
||||
"if(size) *size = ret;\n"
|
||||
"return 0;\n");
|
||||
|
||||
fprintf (codefile, "}\n\n");
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2001 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -39,15 +39,76 @@ static void
|
||||
encode_primitive (const char *typename, const char *name)
|
||||
{
|
||||
fprintf (codefile,
|
||||
"e = encode_%s(p, len, %s, &l);\n"
|
||||
"BACK;\n",
|
||||
"e = der_put_%s(p, len, %s, &l);\n"
|
||||
"if (e) return e;\np -= l; len -= l; ret += l;\n\n",
|
||||
typename,
|
||||
name);
|
||||
}
|
||||
|
||||
static void
|
||||
const char *
|
||||
classname(Der_class class)
|
||||
{
|
||||
const char *cn[] = { "ASN1_C_UNIV", "ASN1_C_APPL",
|
||||
"ASN1_C_CONTEXT", "ASN1_C_PRIV" };
|
||||
if(class < ASN1_C_UNIV || class > ASN1_C_PRIVATE)
|
||||
return "???";
|
||||
return cn[class];
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
valuename(Der_class class, int value)
|
||||
{
|
||||
static char s[32];
|
||||
struct {
|
||||
int value;
|
||||
char *s;
|
||||
} *p, values[] = {
|
||||
#define X(Y) { Y, #Y }
|
||||
X(UT_BMPString),
|
||||
X(UT_BitString),
|
||||
X(UT_Boolean),
|
||||
X(UT_EmbeddedPDV),
|
||||
X(UT_Enumerated),
|
||||
X(UT_External),
|
||||
X(UT_GeneralString),
|
||||
X(UT_GeneralizedTime),
|
||||
X(UT_GraphicString),
|
||||
X(UT_IA5String),
|
||||
X(UT_Integer),
|
||||
X(UT_Null),
|
||||
X(UT_NumericString),
|
||||
X(UT_OID),
|
||||
X(UT_ObjectDescriptor),
|
||||
X(UT_OctetString),
|
||||
X(UT_PrintableString),
|
||||
X(UT_Real),
|
||||
X(UT_RelativeOID),
|
||||
X(UT_Sequence),
|
||||
X(UT_Set),
|
||||
X(UT_TeletexString),
|
||||
X(UT_UTCTime),
|
||||
X(UT_UTF8String),
|
||||
X(UT_UniversalString),
|
||||
X(UT_VideotexString),
|
||||
X(UT_VisibleString),
|
||||
#undef X
|
||||
{ -1, NULL }
|
||||
};
|
||||
if(class == ASN1_C_UNIV) {
|
||||
for(p = values; p->value != -1; p++)
|
||||
if(p->value == value)
|
||||
return p->s;
|
||||
}
|
||||
snprintf(s, sizeof(s), "%d", value);
|
||||
return s;
|
||||
}
|
||||
|
||||
static int
|
||||
encode_type (const char *name, const Type *t)
|
||||
{
|
||||
int constructed = 1;
|
||||
|
||||
switch (t->type) {
|
||||
case TType:
|
||||
#if 0
|
||||
@@ -55,45 +116,60 @@ encode_type (const char *name, const Type *t)
|
||||
#endif
|
||||
fprintf (codefile,
|
||||
"e = encode_%s(p, len, %s, &l);\n"
|
||||
"BACK;\n",
|
||||
"if (e) return e;\np -= l; len -= l; ret += l;\n\n",
|
||||
t->symbol->gen_name, name);
|
||||
break;
|
||||
case TInteger:
|
||||
if(t->members == NULL)
|
||||
encode_primitive ("integer", name);
|
||||
else {
|
||||
if(t->members) {
|
||||
char *s;
|
||||
asprintf(&s, "(const int*)%s", name);
|
||||
if(s == NULL)
|
||||
errx(1, "out of memory");
|
||||
encode_primitive ("integer", s);
|
||||
free(s);
|
||||
}
|
||||
} else if (t->range == NULL) {
|
||||
encode_primitive ("heim_integer", name);
|
||||
} else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
|
||||
encode_primitive ("integer", name);
|
||||
} else if (t->range->min == 0 && t->range->max == UINT_MAX) {
|
||||
encode_primitive ("unsigned", name);
|
||||
} else if (t->range->min == 0 && t->range->max == INT_MAX) {
|
||||
encode_primitive ("unsigned", name);
|
||||
} else
|
||||
errx(1, "%s: unsupported range %d -> %d",
|
||||
name, t->range->min, t->range->max);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TUInteger:
|
||||
encode_primitive ("unsigned", name);
|
||||
case TBoolean:
|
||||
encode_primitive ("boolean", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TOctetString:
|
||||
encode_primitive ("octet_string", name);
|
||||
break;
|
||||
case TOID :
|
||||
encode_primitive ("oid", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TBitString: {
|
||||
Member *m;
|
||||
int pos;
|
||||
int rest;
|
||||
int tag = -1;
|
||||
|
||||
if (t->members == NULL)
|
||||
if (ASN1_TAILQ_EMPTY(t->members)) {
|
||||
encode_primitive("bit_string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf (codefile, "{\n"
|
||||
"unsigned char c = 0;\n");
|
||||
if (!rfc1510_bitstring)
|
||||
fprintf (codefile,
|
||||
"int bit_set = 0;\n");
|
||||
#if 0
|
||||
pos = t->members->prev->val;
|
||||
/* fix for buggy MIT (and OSF?) code */
|
||||
if (pos > 31)
|
||||
abort ();
|
||||
#endif
|
||||
/*
|
||||
* It seems that if we do not always set pos to 31 here, the MIT
|
||||
* code will do the wrong thing.
|
||||
@@ -101,139 +177,293 @@ encode_type (const char *name, const Type *t)
|
||||
* I hate ASN.1 (and DER), but I hate it even more when everybody
|
||||
* has to screw it up differently.
|
||||
*/
|
||||
pos = 31;
|
||||
rest = 7 - (pos % 8);
|
||||
pos = ASN1_TAILQ_LAST(t->members, memhead)->val;
|
||||
if (rfc1510_bitstring) {
|
||||
if (pos < 31)
|
||||
pos = 31;
|
||||
rest = 7 - (pos % 8);
|
||||
} else
|
||||
rest = 0;
|
||||
|
||||
for (m = t->members->prev; m && tag != m->val; m = m->prev) {
|
||||
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
|
||||
while (m->val / 8 < pos / 8) {
|
||||
if (!rfc1510_bitstring)
|
||||
fprintf (codefile,
|
||||
"if (c != 0 || bit_set) {\n");
|
||||
fprintf (codefile,
|
||||
"if (len < 1) return ASN1_OVERFLOW;\n"
|
||||
"*p-- = c; len--; ret++;\n"
|
||||
"c = 0;\n");
|
||||
if (!rfc1510_bitstring)
|
||||
fprintf (codefile,
|
||||
"bit_set = 1;\n"
|
||||
"}\n");
|
||||
pos -= 8;
|
||||
}
|
||||
fprintf (codefile,
|
||||
"if(%s->%s) c |= 1<<%d;\n", name, m->gen_name,
|
||||
7 - m->val % 8);
|
||||
|
||||
if (tag == -1)
|
||||
tag = m->val;
|
||||
"if((%s)->%s) {\n"
|
||||
"c |= 1<<%d;\n",
|
||||
name, m->gen_name, 7 - m->val % 8);
|
||||
if (!rfc1510_bitstring)
|
||||
rest = 7 - m->val % 8;
|
||||
fprintf (codefile,
|
||||
"}\n");
|
||||
}
|
||||
|
||||
if (!rfc1510_bitstring)
|
||||
fprintf (codefile,
|
||||
"if (c != 0 || bit_set) {\n");
|
||||
fprintf (codefile,
|
||||
"*p-- = c;\n"
|
||||
"if (len < 1) return ASN1_OVERFLOW;\n"
|
||||
"*p-- = c; len--; ret++;\n");
|
||||
if (!rfc1510_bitstring)
|
||||
fprintf (codefile,
|
||||
"}\n");
|
||||
|
||||
fprintf (codefile,
|
||||
"if (len < 1) return ASN1_OVERFLOW;\n"
|
||||
"*p-- = %d;\n"
|
||||
"len -= 2;\n"
|
||||
"ret += 2;\n"
|
||||
"}\n\n"
|
||||
"e = der_put_length_and_tag (p, len, ret, ASN1_C_UNIV, PRIM,"
|
||||
"UT_BitString, &l);\n"
|
||||
"BACK;\n",
|
||||
"len -= 1;\n"
|
||||
"ret += 1;\n"
|
||||
"}\n\n",
|
||||
rest);
|
||||
constructed = 0;
|
||||
break;
|
||||
}
|
||||
case TEnumerated : {
|
||||
encode_primitive ("enumerated", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case TSet:
|
||||
case TSequence: {
|
||||
Member *m;
|
||||
int tag = -1;
|
||||
int oldret_counter = unique_get_next();
|
||||
|
||||
if (t->members == NULL)
|
||||
break;
|
||||
|
||||
for (m = t->members->prev; m && tag != m->val; m = m->prev) {
|
||||
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
|
||||
char *s;
|
||||
|
||||
if (m->ellipsis)
|
||||
continue;
|
||||
|
||||
asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
fprintf(codefile, "/* %s */\n", m->name);
|
||||
if (m->optional)
|
||||
fprintf (codefile,
|
||||
"if(%s)\n",
|
||||
"if(%s) ",
|
||||
s);
|
||||
#if 1
|
||||
fprintf (codefile, "{\n"
|
||||
"int oldret%d = ret;\n"
|
||||
"ret = 0;\n",
|
||||
oldret_counter);
|
||||
#endif
|
||||
else if(m->defval)
|
||||
gen_compare_defval(s + 1, m->defval);
|
||||
fprintf (codefile, "{\n");
|
||||
fprintf (codefile, "size_t oldret = ret;\n");
|
||||
fprintf (codefile, "ret = 0;\n");
|
||||
encode_type (s, m->type);
|
||||
fprintf (codefile,
|
||||
"e = der_put_length_and_tag (p, len, ret, ASN1_C_CONTEXT, CONS, "
|
||||
"%d, &l);\n"
|
||||
"BACK;\n",
|
||||
m->val);
|
||||
#if 1
|
||||
fprintf (codefile,
|
||||
"ret += oldret%d;\n"
|
||||
"}\n",
|
||||
oldret_counter);
|
||||
#endif
|
||||
if (tag == -1)
|
||||
tag = m->val;
|
||||
fprintf (codefile, "ret += oldret;\n");
|
||||
fprintf (codefile, "}\n");
|
||||
free (s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSetOf: {
|
||||
|
||||
fprintf(codefile,
|
||||
"{\n"
|
||||
"struct heim_octet_string *val;\n"
|
||||
"size_t elen, totallen = 0;\n"
|
||||
"int eret;\n");
|
||||
|
||||
fprintf(codefile,
|
||||
"val = malloc(sizeof(val[0]) * (%s)->len);\n"
|
||||
"if (val == NULL && (%s)->len != 0) return ENOMEM;\n",
|
||||
name, name);
|
||||
|
||||
fprintf(codefile,
|
||||
"for(i = 0; i < (%s)->len; i++) {\n",
|
||||
name);
|
||||
|
||||
fprintf(codefile,
|
||||
"ASN1_MALLOC_ENCODE(%s, val[i].data, "
|
||||
"val[i].length, &(%s)->val[i], &elen, eret);\n",
|
||||
t->subtype->symbol->gen_name,
|
||||
name);
|
||||
|
||||
fprintf(codefile,
|
||||
"if(eret) {\n"
|
||||
"i--;\n"
|
||||
"while (i >= 0) {\n"
|
||||
"free(val[i].data);\n"
|
||||
"i--;\n"
|
||||
"}\n"
|
||||
"free(val);\n"
|
||||
"return eret;\n"
|
||||
"}\n"
|
||||
"totallen += elen;\n"
|
||||
"}\n");
|
||||
|
||||
fprintf(codefile,
|
||||
"if (totallen > len) {\n"
|
||||
"for (i = 0; i < (%s)->len; i++) {\n"
|
||||
"free(val[i].data);\n"
|
||||
"}\n"
|
||||
"free(val);\n"
|
||||
"return ASN1_OVERFLOW;\n"
|
||||
"}\n",
|
||||
name);
|
||||
|
||||
fprintf(codefile,
|
||||
"qsort(val, (%s)->len, sizeof(val[0]), _heim_der_set_sort);\n",
|
||||
name);
|
||||
|
||||
fprintf (codefile,
|
||||
"e = der_put_length_and_tag (p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);\n"
|
||||
"BACK;\n");
|
||||
"for(i = (%s)->len - 1; i >= 0; --i) {\n"
|
||||
"p -= val[i].length;\n"
|
||||
"ret += val[i].length;\n"
|
||||
"memcpy(p + 1, val[i].data, val[i].length);\n"
|
||||
"free(val[i].data);\n"
|
||||
"}\n"
|
||||
"free(val);\n"
|
||||
"}\n",
|
||||
name);
|
||||
break;
|
||||
}
|
||||
case TSequenceOf: {
|
||||
int oldret_counter = unique_get_next();
|
||||
char *n;
|
||||
|
||||
fprintf (codefile,
|
||||
"for(i = (%s)->len - 1; i >= 0; --i) {\n"
|
||||
#if 1
|
||||
"int oldret%d = ret;\n"
|
||||
"size_t oldret = ret;\n"
|
||||
"ret = 0;\n",
|
||||
#else
|
||||
,
|
||||
#endif
|
||||
name, oldret_counter);
|
||||
name);
|
||||
asprintf (&n, "&(%s)->val[i]", name);
|
||||
if (n == NULL)
|
||||
errx(1, "malloc");
|
||||
encode_type (n, t->subtype);
|
||||
fprintf (codefile,
|
||||
#if 1
|
||||
"ret += oldret%d;\n"
|
||||
#endif
|
||||
"}\n"
|
||||
"e = der_put_length_and_tag (p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);\n"
|
||||
"BACK;\n"
|
||||
#if 1
|
||||
, oldret_counter
|
||||
#endif
|
||||
);
|
||||
"ret += oldret;\n"
|
||||
"}\n");
|
||||
free (n);
|
||||
break;
|
||||
}
|
||||
case TGeneralizedTime:
|
||||
encode_primitive ("generalized_time", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TGeneralString:
|
||||
encode_primitive ("general_string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TTag: {
|
||||
int c = encode_type (name, t->subtype);
|
||||
fprintf (codefile,
|
||||
"e = der_put_length_and_tag (p, len, ret, %s, %s, %s, &l);\n"
|
||||
"if (e) return e;\np -= l; len -= l; ret += l;\n\n",
|
||||
classname(t->tag.tagclass),
|
||||
c ? "CONS" : "PRIM",
|
||||
valuename(t->tag.tagclass, t->tag.tagvalue));
|
||||
break;
|
||||
}
|
||||
case TChoice:{
|
||||
Member *m, *have_ellipsis = NULL;
|
||||
char *s;
|
||||
|
||||
if (t->members == NULL)
|
||||
break;
|
||||
|
||||
fprintf(codefile, "\n");
|
||||
|
||||
asprintf (&s, "(%s)", name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
fprintf(codefile, "switch(%s->element) {\n", s);
|
||||
|
||||
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
|
||||
char *s2;
|
||||
|
||||
if (m->ellipsis) {
|
||||
have_ellipsis = m;
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf (codefile, "case %s: {", m->label);
|
||||
asprintf(&s2, "%s(%s)->u.%s", m->optional ? "" : "&",
|
||||
s, m->gen_name);
|
||||
if (s2 == NULL)
|
||||
errx(1, "malloc");
|
||||
if (m->optional)
|
||||
fprintf (codefile, "if(%s) {\n", s2);
|
||||
fprintf (codefile, "size_t oldret;\n");
|
||||
fprintf (codefile, "oldret = ret;\n");
|
||||
fprintf (codefile, "ret = 0;\n");
|
||||
constructed = encode_type (s2, m->type);
|
||||
fprintf (codefile, "ret += oldret;\n");
|
||||
if(m->optional)
|
||||
fprintf (codefile, "}\n");
|
||||
fprintf(codefile, "break;\n");
|
||||
fprintf(codefile, "}\n");
|
||||
free (s2);
|
||||
}
|
||||
free (s);
|
||||
if (have_ellipsis) {
|
||||
fprintf(codefile,
|
||||
"case %s: {\n"
|
||||
"if (len < %s->u.%s.length)\n"
|
||||
"return ASN1_OVERFLOW;\n"
|
||||
"p -= %s->u.%s.length;\n"
|
||||
"ret += %s->u.%s.length;\n"
|
||||
"memcpy(p + 1, %s->u.%s.data, %s->u.%s.length);\n"
|
||||
"break;\n"
|
||||
"}\n",
|
||||
have_ellipsis->label,
|
||||
name, have_ellipsis->gen_name,
|
||||
name, have_ellipsis->gen_name,
|
||||
name, have_ellipsis->gen_name,
|
||||
name, have_ellipsis->gen_name,
|
||||
name, have_ellipsis->gen_name);
|
||||
}
|
||||
fprintf(codefile, "};\n");
|
||||
break;
|
||||
}
|
||||
case TOID:
|
||||
encode_primitive ("oid", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TUTCTime:
|
||||
encode_primitive ("utctime", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TUTF8String:
|
||||
encode_primitive ("utf8string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TPrintableString:
|
||||
encode_primitive ("printable_string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TIA5String:
|
||||
encode_primitive ("ia5_string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TBMPString:
|
||||
encode_primitive ("bmp_string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TUniversalString:
|
||||
encode_primitive ("universal_string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TNull:
|
||||
fprintf (codefile,
|
||||
"e = encode_nulltype(p, len, &l);\n"
|
||||
"BACK;\n");
|
||||
break;
|
||||
case TApplication:
|
||||
encode_type (name, t->subtype);
|
||||
fprintf (codefile,
|
||||
"e = der_put_length_and_tag (p, len, ret, ASN1_C_APPL, CONS, %d, &l);\n"
|
||||
"BACK;\n",
|
||||
t->application);
|
||||
break;
|
||||
case TBoolean:
|
||||
encode_primitive ("boolean", name);
|
||||
fprintf (codefile, "/* NULL */\n");
|
||||
constructed = 0;
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
return constructed;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -244,9 +474,6 @@ generate_type_encode (const Symbol *s)
|
||||
"encode_%s(unsigned char *, size_t, const %s *, size_t *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile, "#define BACK if (e) return e; p -= l; len -= l; ret += l\n\n");
|
||||
|
||||
|
||||
fprintf (codefile, "int\n"
|
||||
"encode_%s(unsigned char *p, size_t len,"
|
||||
" const %s *data, size_t *size)\n"
|
||||
@@ -255,20 +482,27 @@ generate_type_encode (const Symbol *s)
|
||||
|
||||
switch (s->type->type) {
|
||||
case TInteger:
|
||||
case TUInteger:
|
||||
case TBoolean:
|
||||
case TOctetString:
|
||||
case TGeneralizedTime:
|
||||
case TGeneralString:
|
||||
case TUTCTime:
|
||||
case TUTF8String:
|
||||
case TPrintableString:
|
||||
case TIA5String:
|
||||
case TBMPString:
|
||||
case TUniversalString:
|
||||
case TNull:
|
||||
case TBitString:
|
||||
case TEnumerated:
|
||||
case TOID:
|
||||
case TSequence:
|
||||
case TSequenceOf:
|
||||
case TApplication:
|
||||
case TSet:
|
||||
case TSetOf:
|
||||
case TTag:
|
||||
case TType:
|
||||
case TChoice:
|
||||
fprintf (codefile,
|
||||
"size_t ret = 0;\n"
|
||||
"size_t l;\n"
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2003 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -42,92 +42,136 @@ free_primitive (const char *typename, const char *name)
|
||||
}
|
||||
|
||||
static void
|
||||
free_type (const char *name, const Type *t)
|
||||
free_type (const char *name, const Type *t, int preserve)
|
||||
{
|
||||
switch (t->type) {
|
||||
case TType:
|
||||
switch (t->type) {
|
||||
case TType:
|
||||
#if 0
|
||||
free_type (name, t->symbol->type);
|
||||
free_type (name, t->symbol->type, preserve);
|
||||
#endif
|
||||
fprintf (codefile, "free_%s(%s);\n", t->symbol->gen_name, name);
|
||||
break;
|
||||
case TInteger:
|
||||
case TUInteger:
|
||||
case TBoolean:
|
||||
case TEnumerated :
|
||||
break;
|
||||
case TOctetString:
|
||||
free_primitive ("octet_string", name);
|
||||
break;
|
||||
case TOID :
|
||||
free_primitive ("oid", name);
|
||||
break;
|
||||
case TBitString: {
|
||||
break;
|
||||
}
|
||||
case TSequence: {
|
||||
Member *m;
|
||||
int tag = -1;
|
||||
fprintf (codefile, "free_%s(%s);\n", t->symbol->gen_name, name);
|
||||
break;
|
||||
case TInteger:
|
||||
case TBoolean:
|
||||
case TEnumerated :
|
||||
case TNull:
|
||||
case TGeneralizedTime:
|
||||
case TUTCTime:
|
||||
break;
|
||||
case TBitString:
|
||||
if (ASN1_TAILQ_EMPTY(t->members))
|
||||
free_primitive("bit_string", name);
|
||||
break;
|
||||
case TOctetString:
|
||||
free_primitive ("octet_string", name);
|
||||
break;
|
||||
case TChoice:
|
||||
case TSet:
|
||||
case TSequence: {
|
||||
Member *m, *have_ellipsis = NULL;
|
||||
|
||||
if (t->members == NULL)
|
||||
break;
|
||||
if (t->members == NULL)
|
||||
break;
|
||||
|
||||
for (m = t->members; m && tag != m->val; m = m->next) {
|
||||
char *s;
|
||||
if ((t->type == TSequence || t->type == TChoice) && preserve)
|
||||
fprintf(codefile, "free_octet_string(&data->_save);\n");
|
||||
|
||||
asprintf (&s, "%s(%s)->%s",
|
||||
m->optional ? "" : "&", name, m->gen_name);
|
||||
if(m->optional)
|
||||
fprintf(codefile, "if(%s) {\n", s);
|
||||
free_type (s, m->type);
|
||||
if(m->optional)
|
||||
fprintf(codefile,
|
||||
"free(%s);\n"
|
||||
"%s = NULL;\n"
|
||||
"}\n", s, s);
|
||||
if (tag == -1)
|
||||
tag = m->val;
|
||||
free (s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSequenceOf: {
|
||||
char *n;
|
||||
if(t->type == TChoice)
|
||||
fprintf(codefile, "switch((%s)->element) {\n", name);
|
||||
|
||||
fprintf (codefile, "while((%s)->len){\n", name);
|
||||
asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name);
|
||||
free_type(n, t->subtype);
|
||||
fprintf(codefile,
|
||||
"(%s)->len--;\n"
|
||||
"}\n",
|
||||
name);
|
||||
fprintf(codefile,
|
||||
"free((%s)->val);\n"
|
||||
"(%s)->val = NULL;\n", name, name);
|
||||
free(n);
|
||||
break;
|
||||
}
|
||||
case TGeneralizedTime:
|
||||
break;
|
||||
case TGeneralString:
|
||||
free_primitive ("general_string", name);
|
||||
break;
|
||||
case TUTF8String:
|
||||
free_primitive ("utf8string", name);
|
||||
break;
|
||||
case TNull:
|
||||
break;
|
||||
case TApplication:
|
||||
free_type (name, t->subtype);
|
||||
break;
|
||||
default :
|
||||
abort ();
|
||||
}
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *s;
|
||||
|
||||
if (m->ellipsis){
|
||||
have_ellipsis = m;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(t->type == TChoice)
|
||||
fprintf(codefile, "case %s:\n", m->label);
|
||||
asprintf (&s, "%s(%s)->%s%s",
|
||||
m->optional ? "" : "&", name,
|
||||
t->type == TChoice ? "u." : "", m->gen_name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
if(m->optional)
|
||||
fprintf(codefile, "if(%s) {\n", s);
|
||||
free_type (s, m->type, FALSE);
|
||||
if(m->optional)
|
||||
fprintf(codefile,
|
||||
"free(%s);\n"
|
||||
"%s = NULL;\n"
|
||||
"}\n",s, s);
|
||||
free (s);
|
||||
if(t->type == TChoice)
|
||||
fprintf(codefile, "break;\n");
|
||||
}
|
||||
|
||||
if(t->type == TChoice) {
|
||||
if (have_ellipsis)
|
||||
fprintf(codefile,
|
||||
"case %s:\n"
|
||||
"free_octet_string(&(%s)->u.%s);\n"
|
||||
"break;",
|
||||
have_ellipsis->label,
|
||||
name, have_ellipsis->gen_name);
|
||||
fprintf(codefile, "}\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSetOf:
|
||||
case TSequenceOf: {
|
||||
char *n;
|
||||
|
||||
fprintf (codefile, "while((%s)->len){\n", name);
|
||||
asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name);
|
||||
if (n == NULL)
|
||||
errx(1, "malloc");
|
||||
free_type(n, t->subtype, FALSE);
|
||||
fprintf(codefile,
|
||||
"(%s)->len--;\n"
|
||||
"}\n",
|
||||
name);
|
||||
fprintf(codefile,
|
||||
"free((%s)->val);\n"
|
||||
"(%s)->val = NULL;\n", name, name);
|
||||
free(n);
|
||||
break;
|
||||
}
|
||||
case TGeneralString:
|
||||
free_primitive ("general_string", name);
|
||||
break;
|
||||
case TUTF8String:
|
||||
free_primitive ("utf8string", name);
|
||||
break;
|
||||
case TPrintableString:
|
||||
free_primitive ("printable_string", name);
|
||||
break;
|
||||
case TIA5String:
|
||||
free_primitive ("ia5_string", name);
|
||||
break;
|
||||
case TBMPString:
|
||||
free_primitive ("bmp_string", name);
|
||||
break;
|
||||
case TUniversalString:
|
||||
free_primitive ("universal_string", name);
|
||||
break;
|
||||
case TTag:
|
||||
free_type (name, t->subtype, preserve);
|
||||
break;
|
||||
case TOID :
|
||||
free_primitive ("oid", name);
|
||||
break;
|
||||
default :
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
generate_type_free (const Symbol *s)
|
||||
{
|
||||
int preserve = preserve_type(s->name) ? TRUE : FALSE;
|
||||
|
||||
fprintf (headerfile,
|
||||
"void free_%s (%s *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
@@ -137,7 +181,7 @@ generate_type_free (const Symbol *s)
|
||||
"{\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
free_type ("data", s->type);
|
||||
free_type ("data", s->type, preserve);
|
||||
fprintf (codefile, "}\n\n");
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1999 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997, 1999, 2000, 2003 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -36,56 +36,48 @@
|
||||
RCSID("$Id$");
|
||||
|
||||
static void
|
||||
generate_2int (const Symbol *s)
|
||||
generate_2int (const Type *t, const char *gen_name)
|
||||
{
|
||||
Type *t = s->type;
|
||||
Member *m;
|
||||
int tag = -1;
|
||||
|
||||
fprintf (headerfile,
|
||||
"unsigned %s2int(%s);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
gen_name, gen_name);
|
||||
|
||||
fprintf (codefile,
|
||||
"unsigned %s2int(%s f)\n"
|
||||
"{\n"
|
||||
"unsigned r = 0;\n",
|
||||
s->gen_name, s->gen_name);
|
||||
gen_name, gen_name);
|
||||
|
||||
for (m = t->members; m && m->val != tag; m = m->next) {
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
fprintf (codefile, "if(f.%s) r |= (1U << %d);\n",
|
||||
m->gen_name, m->val);
|
||||
|
||||
if (tag == -1)
|
||||
tag = m->val;
|
||||
}
|
||||
fprintf (codefile, "return r;\n"
|
||||
"}\n\n");
|
||||
}
|
||||
|
||||
static void
|
||||
generate_int2 (const Symbol *s)
|
||||
generate_int2 (const Type *t, const char *gen_name)
|
||||
{
|
||||
Type *t = s->type;
|
||||
Member *m;
|
||||
int tag = -1;
|
||||
|
||||
fprintf (headerfile,
|
||||
"%s int2%s(unsigned);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
gen_name, gen_name);
|
||||
|
||||
fprintf (codefile,
|
||||
"%s int2%s(unsigned n)\n"
|
||||
"{\n"
|
||||
"\t%s flags;\n\n",
|
||||
s->gen_name, s->gen_name, s->gen_name);
|
||||
gen_name, gen_name, gen_name);
|
||||
|
||||
for (m = t->members; m && m->val != tag; m = m->next) {
|
||||
fprintf (codefile, "\tflags.%s = (n >> %d) & 1;\n",
|
||||
m->gen_name, m->val);
|
||||
|
||||
if (tag == -1)
|
||||
tag = m->val;
|
||||
if(t->members) {
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
fprintf (codefile, "\tflags.%s = (n >> %d) & 1;\n",
|
||||
m->gen_name, m->val);
|
||||
}
|
||||
}
|
||||
fprintf (codefile, "\treturn flags;\n"
|
||||
"}\n\n");
|
||||
@@ -96,28 +88,24 @@ generate_int2 (const Symbol *s)
|
||||
*/
|
||||
|
||||
static void
|
||||
generate_units (const Symbol *s)
|
||||
generate_units (const Type *t, const char *gen_name)
|
||||
{
|
||||
Type *t = s->type;
|
||||
Member *m;
|
||||
int tag = -1;
|
||||
|
||||
fprintf (headerfile,
|
||||
"const struct units * asn1_%s_units(void);",
|
||||
s->gen_name);
|
||||
gen_name);
|
||||
|
||||
fprintf (codefile,
|
||||
"static struct units %s_units[] = {\n",
|
||||
s->gen_name);
|
||||
gen_name);
|
||||
|
||||
if(t->members)
|
||||
for (m = t->members->prev; m && m->val != tag; m = m->prev) {
|
||||
if(t->members) {
|
||||
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
|
||||
fprintf (codefile,
|
||||
"\t{\"%s\",\t1U << %d},\n", m->gen_name, m->val);
|
||||
|
||||
if (tag == -1)
|
||||
tag = m->val;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf (codefile,
|
||||
"\t{NULL,\t0}\n"
|
||||
@@ -127,19 +115,24 @@ generate_units (const Symbol *s)
|
||||
"const struct units * asn1_%s_units(void){\n"
|
||||
"return %s_units;\n"
|
||||
"}\n\n",
|
||||
s->gen_name, s->gen_name);
|
||||
gen_name, gen_name);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
generate_glue (const Symbol *s)
|
||||
generate_glue (const Type *t, const char *gen_name)
|
||||
{
|
||||
switch(s->type->type) {
|
||||
switch(t->type) {
|
||||
case TTag:
|
||||
generate_glue(t->subtype, gen_name);
|
||||
break;
|
||||
case TBitString :
|
||||
generate_2int (s);
|
||||
generate_int2 (s);
|
||||
generate_units (s);
|
||||
if (!ASN1_TAILQ_EMPTY(t->members)) {
|
||||
generate_2int (t, gen_name);
|
||||
generate_int2 (t, gen_name);
|
||||
generate_units (t, gen_name);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2000 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -43,7 +43,22 @@ length_primitive (const char *typename,
|
||||
fprintf (codefile, "%s += length_%s(%s);\n", variable, typename, name);
|
||||
}
|
||||
|
||||
static void
|
||||
static size_t
|
||||
length_tag(unsigned int tag)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
||||
if(tag <= 30)
|
||||
return 1;
|
||||
while(tag) {
|
||||
tag /= 128;
|
||||
len++;
|
||||
}
|
||||
return len + 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
length_type (const char *name, const Type *t, const char *variable)
|
||||
{
|
||||
switch (t->type) {
|
||||
@@ -55,19 +70,28 @@ length_type (const char *name, const Type *t, const char *variable)
|
||||
variable, t->symbol->gen_name, name);
|
||||
break;
|
||||
case TInteger:
|
||||
if(t->members == NULL)
|
||||
length_primitive ("integer", name, variable);
|
||||
else {
|
||||
char *s;
|
||||
asprintf(&s, "(const int*)%s", name);
|
||||
if(s == NULL)
|
||||
if(t->members) {
|
||||
char *s;
|
||||
asprintf(&s, "(const int*)%s", name);
|
||||
if(s == NULL)
|
||||
errx (1, "out of memory");
|
||||
length_primitive ("integer", s, variable);
|
||||
free(s);
|
||||
}
|
||||
length_primitive ("integer", s, variable);
|
||||
free(s);
|
||||
} else if (t->range == NULL) {
|
||||
length_primitive ("heim_integer", name, variable);
|
||||
} else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
|
||||
length_primitive ("integer", name, variable);
|
||||
} else if (t->range->min == 0 && t->range->max == UINT_MAX) {
|
||||
length_primitive ("unsigned", name, variable);
|
||||
} else if (t->range->min == 0 && t->range->max == INT_MAX) {
|
||||
length_primitive ("unsigned", name, variable);
|
||||
} else
|
||||
errx(1, "%s: unsupported range %d -> %d",
|
||||
name, t->range->min, t->range->max);
|
||||
|
||||
break;
|
||||
case TUInteger:
|
||||
length_primitive ("unsigned", name, variable);
|
||||
case TBoolean:
|
||||
fprintf (codefile, "%s += 1;\n", variable);
|
||||
break;
|
||||
case TEnumerated :
|
||||
length_primitive ("enumerated", name, variable);
|
||||
@@ -75,71 +99,112 @@ length_type (const char *name, const Type *t, const char *variable)
|
||||
case TOctetString:
|
||||
length_primitive ("octet_string", name, variable);
|
||||
break;
|
||||
case TOID :
|
||||
length_primitive ("oid", name, variable);
|
||||
break;
|
||||
case TBitString: {
|
||||
/*
|
||||
* XXX - Hope this is correct
|
||||
* look at TBitString case in `encode_type'
|
||||
*/
|
||||
fprintf (codefile, "%s += 7;\n", variable);
|
||||
if (ASN1_TAILQ_EMPTY(t->members))
|
||||
length_primitive("bit_string", name, variable);
|
||||
else {
|
||||
if (!rfc1510_bitstring) {
|
||||
Member *m;
|
||||
int pos = ASN1_TAILQ_LAST(t->members, memhead)->val;
|
||||
|
||||
fprintf(codefile,
|
||||
"do {\n");
|
||||
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
|
||||
while (m->val / 8 < pos / 8) {
|
||||
pos -= 8;
|
||||
}
|
||||
fprintf (codefile,
|
||||
"if((%s)->%s) { %s += %d; break; }\n",
|
||||
name, m->gen_name, variable, (pos + 8) / 8);
|
||||
}
|
||||
fprintf(codefile,
|
||||
"} while(0);\n");
|
||||
fprintf (codefile, "%s += 1;\n", variable);
|
||||
} else {
|
||||
fprintf (codefile, "%s += 5;\n", variable);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSequence: {
|
||||
Member *m;
|
||||
int tag = -1;
|
||||
int oldret_counter = unique_get_next();
|
||||
case TSet:
|
||||
case TSequence:
|
||||
case TChoice: {
|
||||
Member *m, *have_ellipsis = NULL;
|
||||
|
||||
if (t->members == NULL)
|
||||
break;
|
||||
|
||||
for (m = t->members; m && tag != m->val; m = m->next) {
|
||||
if(t->type == TChoice)
|
||||
fprintf (codefile, "switch((%s)->element) {\n", name);
|
||||
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *s;
|
||||
|
||||
asprintf (&s, "%s(%s)->%s",
|
||||
m->optional ? "" : "&", name, m->gen_name);
|
||||
if (m->ellipsis) {
|
||||
have_ellipsis = m;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(t->type == TChoice)
|
||||
fprintf(codefile, "case %s:\n", m->label);
|
||||
|
||||
asprintf (&s, "%s(%s)->%s%s",
|
||||
m->optional ? "" : "&", name,
|
||||
t->type == TChoice ? "u." : "", m->gen_name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
if (m->optional)
|
||||
fprintf (codefile, "if(%s)", s);
|
||||
else if(m->defval)
|
||||
gen_compare_defval(s + 1, m->defval);
|
||||
fprintf (codefile, "{\n"
|
||||
"int oldret%d = %s;\n"
|
||||
"%s = 0;\n", oldret_counter, variable, variable);
|
||||
"size_t oldret = %s;\n"
|
||||
"%s = 0;\n", variable, variable);
|
||||
length_type (s, m->type, "ret");
|
||||
fprintf (codefile, "%s += 1 + length_len(%s) + oldret%d;\n",
|
||||
variable, variable, oldret_counter);
|
||||
fprintf (codefile, "ret += oldret;\n");
|
||||
fprintf (codefile, "}\n");
|
||||
if (tag == -1)
|
||||
tag = m->val;
|
||||
free (s);
|
||||
if(t->type == TChoice)
|
||||
fprintf(codefile, "break;\n");
|
||||
}
|
||||
if(t->type == TChoice) {
|
||||
if (have_ellipsis)
|
||||
fprintf(codefile,
|
||||
"case %s:\n"
|
||||
"ret += %s->u.%s.length;\n"
|
||||
"break;\n",
|
||||
have_ellipsis->label,
|
||||
name,
|
||||
have_ellipsis->gen_name);
|
||||
fprintf (codefile, "}\n"); /* switch */
|
||||
}
|
||||
fprintf (codefile,
|
||||
"%s += 1 + length_len(%s);\n", variable, variable);
|
||||
break;
|
||||
}
|
||||
case TSetOf:
|
||||
case TSequenceOf: {
|
||||
char *n;
|
||||
int oldret_counter = unique_get_next();
|
||||
int oldret_counter_inner = unique_get_next();
|
||||
|
||||
fprintf (codefile,
|
||||
"{\n"
|
||||
"int oldret%d = %s;\n"
|
||||
"int oldret = %s;\n"
|
||||
"int i;\n"
|
||||
"%s = 0;\n",
|
||||
oldret_counter, variable, variable);
|
||||
variable, variable);
|
||||
|
||||
fprintf (codefile, "for(i = (%s)->len - 1; i >= 0; --i){\n", name);
|
||||
fprintf (codefile, "int oldret%d = %s;\n"
|
||||
"%s = 0;\n", oldret_counter_inner, variable, variable);
|
||||
fprintf (codefile, "int oldret = %s;\n"
|
||||
"%s = 0;\n", variable, variable);
|
||||
asprintf (&n, "&(%s)->val[i]", name);
|
||||
if (n == NULL)
|
||||
errx(1, "malloc");
|
||||
length_type(n, t->subtype, variable);
|
||||
fprintf (codefile, "%s += oldret%d;\n",
|
||||
variable, oldret_counter_inner);
|
||||
fprintf (codefile, "%s += oldret;\n",
|
||||
variable);
|
||||
fprintf (codefile, "}\n");
|
||||
|
||||
fprintf (codefile,
|
||||
"%s += 1 + length_len(%s) + oldret%d;\n"
|
||||
"}\n", variable, variable, oldret_counter);
|
||||
"%s += oldret;\n"
|
||||
"}\n", variable);
|
||||
free(n);
|
||||
break;
|
||||
}
|
||||
@@ -149,28 +214,43 @@ length_type (const char *name, const Type *t, const char *variable)
|
||||
case TGeneralString:
|
||||
length_primitive ("general_string", name, variable);
|
||||
break;
|
||||
case TUTCTime:
|
||||
length_primitive ("utctime", name, variable);
|
||||
break;
|
||||
case TUTF8String:
|
||||
length_primitive ("utf8string", name, variable);
|
||||
break;
|
||||
case TPrintableString:
|
||||
length_primitive ("printable_string", name, variable);
|
||||
break;
|
||||
case TIA5String:
|
||||
length_primitive ("ia5_string", name, variable);
|
||||
break;
|
||||
case TBMPString:
|
||||
length_primitive ("bmp_string", name, variable);
|
||||
break;
|
||||
case TUniversalString:
|
||||
length_primitive ("universal_string", name, variable);
|
||||
break;
|
||||
case TNull:
|
||||
fprintf (codefile, "%s += length_nulltype();\n", variable);
|
||||
fprintf (codefile, "/* NULL */\n");
|
||||
break;
|
||||
case TApplication:
|
||||
case TTag:
|
||||
length_type (name, t->subtype, variable);
|
||||
fprintf (codefile, "ret += 1 + length_len (ret);\n");
|
||||
fprintf (codefile, "ret += %d + length_len (ret);\n", length_tag(t->tag.tagvalue));
|
||||
break;
|
||||
case TBoolean:
|
||||
length_primitive ("boolean", name, variable);
|
||||
case TOID:
|
||||
length_primitive ("oid", name, variable);
|
||||
break;
|
||||
default :
|
||||
abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
generate_type_length (const Symbol *s)
|
||||
{
|
||||
unique_reset();
|
||||
fprintf (headerfile,
|
||||
"size_t length_%s(const %s *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2001 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997-2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -51,6 +51,8 @@
|
||||
#include <roken.h>
|
||||
#include "hash.h"
|
||||
#include "symbol.h"
|
||||
#include "asn1-common.h"
|
||||
#include "der.h"
|
||||
|
||||
void generate_type (const Symbol *);
|
||||
void generate_constant (const Symbol *);
|
||||
@@ -61,10 +63,14 @@ void generate_type_free (const Symbol *s);
|
||||
void generate_type_length (const Symbol *s);
|
||||
void generate_type_copy (const Symbol *s);
|
||||
void generate_type_maybe (const Symbol *s);
|
||||
void generate_glue (const Symbol *s);
|
||||
void generate_glue (const Type *, const char*);
|
||||
|
||||
const char *classname(Der_class);
|
||||
const char *valuename(Der_class class, int);
|
||||
|
||||
void gen_compare_defval(const char *var, struct value *val);
|
||||
void gen_assign_defval(const char *var, struct value *val);
|
||||
|
||||
void unique_reset(void);
|
||||
int unique_get_next(void);
|
||||
|
||||
void init_generate (const char *filename, const char *basename);
|
||||
const char *get_filename (void);
|
||||
@@ -72,6 +78,12 @@ void close_generate(void);
|
||||
void add_import(const char *module);
|
||||
int yyparse(void);
|
||||
|
||||
int preserve_type(const char *);
|
||||
|
||||
extern FILE *headerfile, *codefile, *logfile;
|
||||
extern int dce_fix;
|
||||
extern int rfc1510_bitstring;
|
||||
|
||||
extern int error_flag;
|
||||
|
||||
#endif /* __GEN_LOCL_H__ */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 2003-2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -34,12 +34,8 @@
|
||||
#ifndef __HEIM_ANY_H__
|
||||
#define __HEIM_ANY_H__ 1
|
||||
|
||||
typedef struct heim_any {
|
||||
size_t length;
|
||||
void *data;
|
||||
} heim_any;
|
||||
|
||||
typedef struct heim_any heim_any_set;
|
||||
typedef struct heim_octet_string heim_any;
|
||||
typedef struct heim_octet_string heim_any_set;
|
||||
|
||||
int encode_heim_any(unsigned char *, size_t, const heim_any *, size_t *);
|
||||
int decode_heim_any(const unsigned char *, size_t, heim_any *, size_t *);
|
||||
@@ -54,5 +50,6 @@ int decode_heim_any_set(const unsigned char *, size_t,
|
||||
void free_heim_any_set(heim_any_set *);
|
||||
size_t length_heim_any_set(const heim_any_set *);
|
||||
int copy_heim_any_set(const heim_any_set *, heim_any_set *);
|
||||
int heim_any_cmp(const heim_any_set *, const heim_any_set *);
|
||||
|
||||
#endif /* __HEIM_ANY_H__ */
|
||||
|
116
lib/asn1/k5.asn1
116
lib/asn1/k5.asn1
@@ -11,7 +11,11 @@ NAME-TYPE ::= INTEGER {
|
||||
KRB5_NT_SRV_XHST(4), -- Service with host as remaining components
|
||||
KRB5_NT_UID(5), -- Unique ID
|
||||
KRB5_NT_X500_PRINCIPAL(6), -- PKINIT
|
||||
KRB5_NT_ENTERPRISE(10) -- May be mapped to principal name
|
||||
KRB5_NT_SMTP_NAME(7), -- Name in form of SMTP email name
|
||||
KRB5_NT_ENTERPRISE_PRINCIPAL(10), -- Windows 2000 UPN
|
||||
KRB5_NT_ENT_PRINCIPAL_AND_ID(-130), -- Windows 2000 UPN and SID
|
||||
KRB5_NT_MS_PRINCIPAL(-128), -- NT 4 style name
|
||||
KRB5_NT_MS_PRINCIPAL_AND_ID(-129) -- NT style name and SID
|
||||
}
|
||||
|
||||
-- message types
|
||||
@@ -49,6 +53,7 @@ PADATA-TYPE ::= INTEGER {
|
||||
KRB5-PADATA-SAM-RESPONSE(13), -- (sam/otp)
|
||||
KRB5-PADATA-PK-AS-REQ-19(14), -- (PKINIT-19)
|
||||
KRB5-PADATA-PK-AS-REP-19(15), -- (PKINIT-19)
|
||||
KRB5-PADATA-PK-AS-REQ-WIN(15), -- (PKINIT - old number)
|
||||
KRB5-PADATA-PK-AS-REQ(16), -- (PKINIT-25)
|
||||
KRB5-PADATA-PK-AS-REP(17), -- (PKINIT-25)
|
||||
KRB5-PADATA-ETYPE-INFO2(19),
|
||||
@@ -58,7 +63,6 @@ PADATA-TYPE ::= INTEGER {
|
||||
KRB5-PADATA-SAM-ETYPE-INFO(23),
|
||||
KRB5-PADATA-SERVER-REFERRAL(25),
|
||||
KRB5-PADATA-TD-KRB-PRINCIPAL(102), -- PrincipalName
|
||||
KRB5-PADATA-TD-KRB-REALM(103), -- Realm
|
||||
KRB5-PADATA-PK-TD-TRUSTED-CERTIFIERS(104), -- PKINIT
|
||||
KRB5-PADATA-PK-TD-CERTIFICATE-INDEX(105), -- PKINIT
|
||||
KRB5-PADATA-TD-APP-DEFINED-ERROR(106), -- application specific
|
||||
@@ -137,9 +141,13 @@ ENCTYPE ::= INTEGER {
|
||||
ETYPE_DES3_CBC_NONE_CMS(-0x100a)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
-- this is sugar to make something ASN1 does not have: unsigned
|
||||
|
||||
UNSIGNED ::= INTEGER (0..4294967295)
|
||||
krb5uint32 ::= INTEGER (0..4294967295)
|
||||
krb5int32 ::= INTEGER (-2147483648..2147483647)
|
||||
|
||||
KerberosString ::= GeneralString
|
||||
|
||||
@@ -156,14 +164,14 @@ Principal ::= SEQUENCE {
|
||||
}
|
||||
|
||||
HostAddress ::= SEQUENCE {
|
||||
addr-type[0] INTEGER,
|
||||
addr-type[0] krb5int32,
|
||||
address[1] OCTET STRING
|
||||
}
|
||||
|
||||
-- This is from RFC1510.
|
||||
--
|
||||
-- HostAddresses ::= SEQUENCE OF SEQUENCE {
|
||||
-- addr-type[0] INTEGER,
|
||||
-- addr-type[0] krb5int32,
|
||||
-- address[1] OCTET STRING
|
||||
-- }
|
||||
|
||||
@@ -174,7 +182,7 @@ HostAddresses ::= SEQUENCE OF HostAddress
|
||||
KerberosTime ::= GeneralizedTime -- Specifying UTC time zone (Z)
|
||||
|
||||
AuthorizationData ::= SEQUENCE OF SEQUENCE {
|
||||
ad-type[0] INTEGER,
|
||||
ad-type[0] krb5int32,
|
||||
ad-data[1] OCTET STRING
|
||||
}
|
||||
|
||||
@@ -243,23 +251,23 @@ LastReq ::= SEQUENCE OF SEQUENCE {
|
||||
|
||||
EncryptedData ::= SEQUENCE {
|
||||
etype[0] ENCTYPE, -- EncryptionType
|
||||
kvno[1] INTEGER OPTIONAL,
|
||||
kvno[1] krb5int32 OPTIONAL,
|
||||
cipher[2] OCTET STRING -- ciphertext
|
||||
}
|
||||
|
||||
EncryptionKey ::= SEQUENCE {
|
||||
keytype[0] INTEGER,
|
||||
keytype[0] krb5int32,
|
||||
keyvalue[1] OCTET STRING
|
||||
}
|
||||
|
||||
-- encoded Transited field
|
||||
TransitedEncoding ::= SEQUENCE {
|
||||
tr-type[0] INTEGER, -- must be registered
|
||||
tr-type[0] krb5int32, -- must be registered
|
||||
contents[1] OCTET STRING
|
||||
}
|
||||
|
||||
Ticket ::= [APPLICATION 1] SEQUENCE {
|
||||
tkt-vno[0] INTEGER,
|
||||
tkt-vno[0] krb5int32,
|
||||
realm[1] Realm,
|
||||
sname[2] PrincipalName,
|
||||
enc-part[3] EncryptedData
|
||||
@@ -285,14 +293,14 @@ Checksum ::= SEQUENCE {
|
||||
}
|
||||
|
||||
Authenticator ::= [APPLICATION 2] SEQUENCE {
|
||||
authenticator-vno[0] INTEGER,
|
||||
authenticator-vno[0] krb5int32,
|
||||
crealm[1] Realm,
|
||||
cname[2] PrincipalName,
|
||||
cksum[3] Checksum OPTIONAL,
|
||||
cusec[4] INTEGER,
|
||||
cusec[4] krb5int32,
|
||||
ctime[5] KerberosTime,
|
||||
subkey[6] EncryptionKey OPTIONAL,
|
||||
seq-number[7] UNSIGNED OPTIONAL,
|
||||
seq-number[7] krb5uint32 OPTIONAL,
|
||||
authorization-data[8] AuthorizationData OPTIONAL
|
||||
}
|
||||
|
||||
@@ -305,7 +313,7 @@ PA-DATA ::= SEQUENCE {
|
||||
ETYPE-INFO-ENTRY ::= SEQUENCE {
|
||||
etype[0] ENCTYPE,
|
||||
salt[1] OCTET STRING OPTIONAL,
|
||||
salttype[2] INTEGER OPTIONAL
|
||||
salttype[2] krb5int32 OPTIONAL
|
||||
}
|
||||
|
||||
ETYPE-INFO ::= SEQUENCE OF ETYPE-INFO-ENTRY
|
||||
@@ -320,6 +328,13 @@ ETYPE-INFO2 ::= SEQUENCE OF ETYPE-INFO2-ENTRY
|
||||
|
||||
METHOD-DATA ::= SEQUENCE OF PA-DATA
|
||||
|
||||
TypedData ::= SEQUENCE {
|
||||
data-type[0] krb5int32,
|
||||
data-value[1] OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
TYPED-DATA ::= SEQUENCE OF TypedData
|
||||
|
||||
KDC-REQ-BODY ::= SEQUENCE {
|
||||
kdc-options[0] KDCOptions,
|
||||
cname[1] PrincipalName OPTIONAL, -- Used only in AS-REQ
|
||||
@@ -329,7 +344,7 @@ KDC-REQ-BODY ::= SEQUENCE {
|
||||
from[4] KerberosTime OPTIONAL,
|
||||
till[5] KerberosTime OPTIONAL,
|
||||
rtime[6] KerberosTime OPTIONAL,
|
||||
nonce[7] INTEGER,
|
||||
nonce[7] krb5int32,
|
||||
etype[8] SEQUENCE OF ENCTYPE, -- EncryptionType,
|
||||
-- in preference order
|
||||
addresses[9] HostAddresses OPTIONAL,
|
||||
@@ -339,7 +354,7 @@ KDC-REQ-BODY ::= SEQUENCE {
|
||||
}
|
||||
|
||||
KDC-REQ ::= SEQUENCE {
|
||||
pvno[1] INTEGER,
|
||||
pvno[1] krb5int32,
|
||||
msg-type[2] MESSAGE-TYPE,
|
||||
padata[3] METHOD-DATA OPTIONAL,
|
||||
req-body[4] KDC-REQ-BODY
|
||||
@@ -353,7 +368,7 @@ TGS-REQ ::= [APPLICATION 12] KDC-REQ
|
||||
|
||||
PA-ENC-TS-ENC ::= SEQUENCE {
|
||||
patimestamp[0] KerberosTime, -- client's time
|
||||
pausec[1] INTEGER OPTIONAL
|
||||
pausec[1] krb5int32 OPTIONAL
|
||||
}
|
||||
|
||||
-- draft-brezak-win2k-krb-authz-01
|
||||
@@ -362,8 +377,11 @@ PA-PAC-REQUEST ::= SEQUENCE {
|
||||
-- should be included or not
|
||||
}
|
||||
|
||||
-- PacketCable provisioning server location, PKT-SP-SEC-I09-030728.pdf
|
||||
PROV-SRV-LOCATION ::= GeneralString
|
||||
|
||||
KDC-REP ::= SEQUENCE {
|
||||
pvno[0] INTEGER,
|
||||
pvno[0] krb5int32,
|
||||
msg-type[1] MESSAGE-TYPE,
|
||||
padata[2] METHOD-DATA OPTIONAL,
|
||||
crealm[3] Realm,
|
||||
@@ -378,7 +396,7 @@ TGS-REP ::= [APPLICATION 13] KDC-REP
|
||||
EncKDCRepPart ::= SEQUENCE {
|
||||
key[0] EncryptionKey,
|
||||
last-req[1] LastReq,
|
||||
nonce[2] INTEGER,
|
||||
nonce[2] krb5int32,
|
||||
key-expiration[3] KerberosTime OPTIONAL,
|
||||
flags[4] TicketFlags,
|
||||
authtime[5] KerberosTime,
|
||||
@@ -394,7 +412,7 @@ EncASRepPart ::= [APPLICATION 25] EncKDCRepPart
|
||||
EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
|
||||
|
||||
AP-REQ ::= [APPLICATION 14] SEQUENCE {
|
||||
pvno[0] INTEGER,
|
||||
pvno[0] krb5int32,
|
||||
msg-type[1] MESSAGE-TYPE,
|
||||
ap-options[2] APOptions,
|
||||
ticket[3] Ticket,
|
||||
@@ -402,50 +420,50 @@ AP-REQ ::= [APPLICATION 14] SEQUENCE {
|
||||
}
|
||||
|
||||
AP-REP ::= [APPLICATION 15] SEQUENCE {
|
||||
pvno[0] INTEGER,
|
||||
pvno[0] krb5int32,
|
||||
msg-type[1] MESSAGE-TYPE,
|
||||
enc-part[2] EncryptedData
|
||||
}
|
||||
|
||||
EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
|
||||
ctime[0] KerberosTime,
|
||||
cusec[1] INTEGER,
|
||||
cusec[1] krb5int32,
|
||||
subkey[2] EncryptionKey OPTIONAL,
|
||||
seq-number[3] UNSIGNED OPTIONAL
|
||||
seq-number[3] krb5uint32 OPTIONAL
|
||||
}
|
||||
|
||||
KRB-SAFE-BODY ::= SEQUENCE {
|
||||
user-data[0] OCTET STRING,
|
||||
timestamp[1] KerberosTime OPTIONAL,
|
||||
usec[2] INTEGER OPTIONAL,
|
||||
seq-number[3] UNSIGNED OPTIONAL,
|
||||
usec[2] krb5int32 OPTIONAL,
|
||||
seq-number[3] krb5uint32 OPTIONAL,
|
||||
s-address[4] HostAddress OPTIONAL,
|
||||
r-address[5] HostAddress OPTIONAL
|
||||
}
|
||||
|
||||
KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
|
||||
pvno[0] INTEGER,
|
||||
pvno[0] krb5int32,
|
||||
msg-type[1] MESSAGE-TYPE,
|
||||
safe-body[2] KRB-SAFE-BODY,
|
||||
cksum[3] Checksum
|
||||
}
|
||||
|
||||
KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
|
||||
pvno[0] INTEGER,
|
||||
pvno[0] krb5int32,
|
||||
msg-type[1] MESSAGE-TYPE,
|
||||
enc-part[3] EncryptedData
|
||||
}
|
||||
EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE {
|
||||
user-data[0] OCTET STRING,
|
||||
timestamp[1] KerberosTime OPTIONAL,
|
||||
usec[2] INTEGER OPTIONAL,
|
||||
seq-number[3] UNSIGNED OPTIONAL,
|
||||
usec[2] krb5int32 OPTIONAL,
|
||||
seq-number[3] krb5uint32 OPTIONAL,
|
||||
s-address[4] HostAddress OPTIONAL, -- sender's addr
|
||||
r-address[5] HostAddress OPTIONAL -- recip's addr
|
||||
}
|
||||
|
||||
KRB-CRED ::= [APPLICATION 22] SEQUENCE {
|
||||
pvno[0] INTEGER,
|
||||
pvno[0] krb5int32,
|
||||
msg-type[1] MESSAGE-TYPE, -- KRB_CRED
|
||||
tickets[2] SEQUENCE OF Ticket,
|
||||
enc-part[3] EncryptedData
|
||||
@@ -467,21 +485,21 @@ KrbCredInfo ::= SEQUENCE {
|
||||
|
||||
EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
|
||||
ticket-info[0] SEQUENCE OF KrbCredInfo,
|
||||
nonce[1] INTEGER OPTIONAL,
|
||||
nonce[1] krb5int32 OPTIONAL,
|
||||
timestamp[2] KerberosTime OPTIONAL,
|
||||
usec[3] INTEGER OPTIONAL,
|
||||
usec[3] krb5int32 OPTIONAL,
|
||||
s-address[4] HostAddress OPTIONAL,
|
||||
r-address[5] HostAddress OPTIONAL
|
||||
}
|
||||
|
||||
KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
|
||||
pvno[0] INTEGER,
|
||||
pvno[0] krb5int32,
|
||||
msg-type[1] MESSAGE-TYPE,
|
||||
ctime[2] KerberosTime OPTIONAL,
|
||||
cusec[3] INTEGER OPTIONAL,
|
||||
cusec[3] krb5int32 OPTIONAL,
|
||||
stime[4] KerberosTime,
|
||||
susec[5] INTEGER,
|
||||
error-code[6] INTEGER,
|
||||
susec[5] krb5int32,
|
||||
error-code[6] krb5int32,
|
||||
crealm[7] Realm OPTIONAL,
|
||||
cname[8] PrincipalName OPTIONAL,
|
||||
realm[9] Realm, -- Correct realm
|
||||
@@ -496,15 +514,15 @@ ChangePasswdDataMS ::= SEQUENCE {
|
||||
targrealm[2] Realm OPTIONAL
|
||||
}
|
||||
|
||||
EtypeList ::= SEQUENCE OF INTEGER
|
||||
EtypeList ::= SEQUENCE OF krb5int32
|
||||
-- the client's proposed enctype list in
|
||||
-- decreasing preference order, favorite choice first
|
||||
|
||||
krb5-pvno INTEGER ::= 5 -- current Kerberos protocol version number
|
||||
pvno krb5int32 ::= 5 -- current Kerberos protocol version number
|
||||
|
||||
-- transited encodings
|
||||
|
||||
DOMAIN-X500-COMPRESS INTEGER ::= 1
|
||||
DOMAIN-X500-COMPRESS krb5int32 ::= 1
|
||||
|
||||
-- authorization data primitives
|
||||
|
||||
@@ -544,7 +562,7 @@ SAMFlags ::= BIT STRING {
|
||||
}
|
||||
|
||||
PA-SAM-CHALLENGE-2-BODY ::= SEQUENCE {
|
||||
sam-type[0] INTEGER,
|
||||
sam-type[0] krb5int32,
|
||||
sam-flags[1] SAMFlags,
|
||||
sam-type-name[2] GeneralString OPTIONAL,
|
||||
sam-track-id[3] GeneralString OPTIONAL,
|
||||
@@ -552,8 +570,8 @@ PA-SAM-CHALLENGE-2-BODY ::= SEQUENCE {
|
||||
sam-challenge[5] GeneralString OPTIONAL,
|
||||
sam-response-prompt[6] GeneralString OPTIONAL,
|
||||
sam-pk-for-sad[7] EncryptionKey OPTIONAL,
|
||||
sam-nonce[8] INTEGER,
|
||||
sam-etype[9] INTEGER,
|
||||
sam-nonce[8] krb5int32,
|
||||
sam-etype[9] krb5int32,
|
||||
...
|
||||
}
|
||||
|
||||
@@ -564,27 +582,31 @@ PA-SAM-CHALLENGE-2 ::= SEQUENCE {
|
||||
}
|
||||
|
||||
PA-SAM-RESPONSE-2 ::= SEQUENCE {
|
||||
sam-type[0] INTEGER,
|
||||
sam-type[0] krb5int32,
|
||||
sam-flags[1] SAMFlags,
|
||||
sam-track-id[2] GeneralString OPTIONAL,
|
||||
sam-enc-nonce-or-sad[3] EncryptedData, -- PA-ENC-SAM-RESPONSE-ENC
|
||||
sam-nonce[4] INTEGER,
|
||||
sam-nonce[4] krb5int32,
|
||||
...
|
||||
}
|
||||
|
||||
PA-ENC-SAM-RESPONSE-ENC ::= SEQUENCE {
|
||||
sam-nonce[0] INTEGER,
|
||||
sam-nonce[0] krb5int32,
|
||||
sam-sad[1] GeneralString OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
-- This is really part of CMS, but its here because KCRYPTO provides
|
||||
-- the crypto framework for CMS glue in heimdal.
|
||||
|
||||
RC2CBCParameter ::= SEQUENCE {
|
||||
rc2ParameterVersion [0] INTEGER,
|
||||
iv [1] OCTET STRING -- exactly 8 octets
|
||||
rc2ParameterVersion krb5int32,
|
||||
iv OCTET STRING -- exactly 8 octets
|
||||
}
|
||||
|
||||
CBCParameter ::= OCTET STRING
|
||||
|
||||
|
||||
END
|
||||
|
||||
-- etags -r '/\([A-Za-z][-A-Za-z0-9]*\).*::=/\1/' k5.asn1
|
||||
|
@@ -37,5 +37,6 @@
|
||||
|
||||
void error_message (const char *, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
extern int error_flag;
|
||||
|
||||
int yylex(void);
|
||||
|
180
lib/asn1/lex.l
180
lib/asn1/lex.l
@@ -1,6 +1,6 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1997 - 2004 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -52,62 +52,118 @@
|
||||
|
||||
static unsigned lineno = 1;
|
||||
|
||||
#define YY_NO_UNPUT
|
||||
|
||||
#undef ECHO
|
||||
|
||||
static void handle_comment(int type);
|
||||
|
||||
static char *handle_string(void);
|
||||
%}
|
||||
|
||||
|
||||
%%
|
||||
INTEGER { return INTEGER; }
|
||||
BOOLEAN { return BOOLEAN; }
|
||||
IMPORTS { return IMPORTS; }
|
||||
FROM { return FROM; }
|
||||
SEQUENCE { return SEQUENCE; }
|
||||
CHOICE { return CHOICE; }
|
||||
OF { return OF; }
|
||||
OCTET { return OCTET; }
|
||||
STRING { return STRING; }
|
||||
GeneralizedTime { return GeneralizedTime; }
|
||||
GeneralString { return GeneralString; }
|
||||
UTF8String { return UTF8String; }
|
||||
NULL { return NULLTYPE; }
|
||||
BIT { return BIT; }
|
||||
APPLICATION { return APPLICATION; }
|
||||
OPTIONAL { return OPTIONAL; }
|
||||
BEGIN { return TBEGIN; }
|
||||
END { return END; }
|
||||
DEFAULT { return DEFAULT; }
|
||||
DEFINITIONS { return DEFINITIONS; }
|
||||
ENUMERATED { return ENUMERATED; }
|
||||
EXTERNAL { return EXTERNAL; }
|
||||
OBJECT { return OBJECT; }
|
||||
IDENTIFIER { return IDENTIFIER; }
|
||||
[-,;{}()|\"] { return *yytext; }
|
||||
ABSENT { return kw_ABSENT; }
|
||||
ABSTRACT-SYNTAX { return kw_ABSTRACT_SYNTAX; }
|
||||
ALL { return kw_ALL; }
|
||||
APPLICATION { return kw_APPLICATION; }
|
||||
AUTOMATIC { return kw_AUTOMATIC; }
|
||||
BEGIN { return kw_BEGIN; }
|
||||
BIT { return kw_BIT; }
|
||||
BMPString { return kw_BMPString; }
|
||||
BOOLEAN { return kw_BOOLEAN; }
|
||||
BY { return kw_BY; }
|
||||
CHARACTER { return kw_CHARACTER; }
|
||||
CHOICE { return kw_CHOICE; }
|
||||
CLASS { return kw_CLASS; }
|
||||
COMPONENT { return kw_COMPONENT; }
|
||||
COMPONENTS { return kw_COMPONENTS; }
|
||||
CONSTRAINED { return kw_CONSTRAINED; }
|
||||
CONTAINING { return kw_CONTAINING; }
|
||||
DEFAULT { return kw_DEFAULT; }
|
||||
DEFINITIONS { return kw_DEFINITIONS; }
|
||||
EMBEDDED { return kw_EMBEDDED; }
|
||||
ENCODED { return kw_ENCODED; }
|
||||
END { return kw_END; }
|
||||
ENUMERATED { return kw_ENUMERATED; }
|
||||
EXCEPT { return kw_EXCEPT; }
|
||||
EXPLICIT { return kw_EXPLICIT; }
|
||||
EXPORTS { return kw_EXPORTS; }
|
||||
EXTENSIBILITY { return kw_EXTENSIBILITY; }
|
||||
EXTERNAL { return kw_EXTERNAL; }
|
||||
FALSE { return kw_FALSE; }
|
||||
FROM { return kw_FROM; }
|
||||
GeneralString { return kw_GeneralString; }
|
||||
GeneralizedTime { return kw_GeneralizedTime; }
|
||||
GraphicString { return kw_GraphicString; }
|
||||
IA5String { return kw_IA5String; }
|
||||
IDENTIFIER { return kw_IDENTIFIER; }
|
||||
IMPLICIT { return kw_IMPLICIT; }
|
||||
IMPLIED { return kw_IMPLIED; }
|
||||
IMPORTS { return kw_IMPORTS; }
|
||||
INCLUDES { return kw_INCLUDES; }
|
||||
INSTANCE { return kw_INSTANCE; }
|
||||
INTEGER { return kw_INTEGER; }
|
||||
INTERSECTION { return kw_INTERSECTION; }
|
||||
ISO646String { return kw_ISO646String; }
|
||||
MAX { return kw_MAX; }
|
||||
MIN { return kw_MIN; }
|
||||
MINUS-INFINITY { return kw_MINUS_INFINITY; }
|
||||
NULL { return kw_NULL; }
|
||||
NumericString { return kw_NumericString; }
|
||||
OBJECT { return kw_OBJECT; }
|
||||
OCTET { return kw_OCTET; }
|
||||
OF { return kw_OF; }
|
||||
OPTIONAL { return kw_OPTIONAL; }
|
||||
ObjectDescriptor { return kw_ObjectDescriptor; }
|
||||
PATTERN { return kw_PATTERN; }
|
||||
PDV { return kw_PDV; }
|
||||
PLUS-INFINITY { return kw_PLUS_INFINITY; }
|
||||
PRESENT { return kw_PRESENT; }
|
||||
PRIVATE { return kw_PRIVATE; }
|
||||
PrintableString { return kw_PrintableString; }
|
||||
REAL { return kw_REAL; }
|
||||
RELATIVE_OID { return kw_RELATIVE_OID; }
|
||||
SEQUENCE { return kw_SEQUENCE; }
|
||||
SET { return kw_SET; }
|
||||
SIZE { return kw_SIZE; }
|
||||
STRING { return kw_STRING; }
|
||||
SYNTAX { return kw_SYNTAX; }
|
||||
T61String { return kw_T61String; }
|
||||
TAGS { return kw_TAGS; }
|
||||
TRUE { return kw_TRUE; }
|
||||
TYPE-IDENTIFIER { return kw_TYPE_IDENTIFIER; }
|
||||
TeletexString { return kw_TeletexString; }
|
||||
UNION { return kw_UNION; }
|
||||
UNIQUE { return kw_UNIQUE; }
|
||||
UNIVERSAL { return kw_UNIVERSAL; }
|
||||
UTCTime { return kw_UTCTime; }
|
||||
UTF8String { return kw_UTF8String; }
|
||||
UniversalString { return kw_UniversalString; }
|
||||
VideotexString { return kw_VideotexString; }
|
||||
VisibleString { return kw_VisibleString; }
|
||||
WITH { return kw_WITH; }
|
||||
[-,;{}()|] { return *yytext; }
|
||||
"[" { return *yytext; }
|
||||
"]" { return *yytext; }
|
||||
::= { return EEQUAL; }
|
||||
-- { handle_comment(0); }
|
||||
\/\* { handle_comment(1); }
|
||||
0x[0-9A-Fa-f]+|[0-9]+ { char *e, *y = yytext;
|
||||
"\"" { yylval.name = handle_string(); return STRING; }
|
||||
|
||||
-?0x[0-9A-Fa-f]+|-?[0-9]+ { char *e, *y = yytext;
|
||||
yylval.constant = strtol((const char *)yytext,
|
||||
&e, 0);
|
||||
if(e == y)
|
||||
error_message("malformed constant (%s)", yytext);
|
||||
else
|
||||
return CONSTANT;
|
||||
return NUMBER;
|
||||
}
|
||||
[A-Za-z][-A-Za-z0-9_]* {
|
||||
yylval.name = strdup ((const char *)yytext);
|
||||
return IDENT;
|
||||
yylval.name = estrdup ((const char *)yytext);
|
||||
return IDENTIFIER;
|
||||
}
|
||||
[ \t] ;
|
||||
\n { ++lineno; }
|
||||
\.\.\. { return DOTDOTDOT; }
|
||||
\.\. { return DOTDOT; }
|
||||
\.\.\. { return ELLIPSIS; }
|
||||
\.\. { return RANGE; }
|
||||
. { error_message("Ignoring char(%c)\n", *yytext); }
|
||||
%%
|
||||
|
||||
@@ -128,6 +184,7 @@ error_message (const char *format, ...)
|
||||
fprintf (stderr, "%s:%d: ", get_filename(), lineno);
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
error_flag++;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -165,6 +222,12 @@ handle_comment(int type)
|
||||
seen_slash = 1;
|
||||
continue;
|
||||
}
|
||||
if(seen_star && c == '/') {
|
||||
if(--level == 0)
|
||||
return;
|
||||
seen_star = 0;
|
||||
continue;
|
||||
}
|
||||
if(c == '*') {
|
||||
if(seen_slash) {
|
||||
level++;
|
||||
@@ -184,3 +247,50 @@ handle_comment(int type)
|
||||
if(c == EOF)
|
||||
error_message("unterminated comment, possibly started on line %d\n", start_lineno);
|
||||
}
|
||||
|
||||
static char *
|
||||
handle_string(void)
|
||||
{
|
||||
int start_lineno = lineno;
|
||||
int c;
|
||||
char buf[1024];
|
||||
char *p = buf;
|
||||
int f = 0;
|
||||
int skip_ws = 0;
|
||||
|
||||
while((c = input()) != EOF) {
|
||||
if(isspace(c) && skip_ws) {
|
||||
if(c == '\n')
|
||||
lineno++;
|
||||
continue;
|
||||
}
|
||||
skip_ws = 0;
|
||||
|
||||
if(c == '"') {
|
||||
if(f) {
|
||||
*p++ = '"';
|
||||
f = 0;
|
||||
} else
|
||||
f = 1;
|
||||
continue;
|
||||
}
|
||||
if(f == 1) {
|
||||
unput(c);
|
||||
break;
|
||||
}
|
||||
if(c == '\n') {
|
||||
lineno++;
|
||||
while(p > buf && isspace((unsigned char)p[-1]))
|
||||
p--;
|
||||
skip_ws = 1;
|
||||
continue;
|
||||
}
|
||||
*p++ = c;
|
||||
}
|
||||
if(c == EOF)
|
||||
error_message("unterminated string, possibly started on line %d\n", start_lineno);
|
||||
*p++ = '\0';
|
||||
fprintf(stderr, "string -- %s\n", buf);
|
||||
return estrdup(buf);
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Kungliga Tekniska Högskolan
|
||||
* Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -33,6 +33,19 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "symbol.h"
|
||||
#ifndef __LIBASN1_H__
|
||||
#define __LIBASN1_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "krb5_asn1.h"
|
||||
#include "der.h"
|
||||
#include "asn1_err.h"
|
||||
#include <parse_units.h>
|
||||
|
||||
#endif /* __LIBASN1_H__ */
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, 1999 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997-2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -33,14 +33,32 @@
|
||||
|
||||
#include "gen_locl.h"
|
||||
#include <getarg.h>
|
||||
#include "lex.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
extern FILE *yyin;
|
||||
|
||||
static getarg_strings preserve;
|
||||
|
||||
int
|
||||
preserve_type(const char *p)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < preserve.num_strings; i++)
|
||||
if (strcmp(preserve.strings[i], p) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dce_fix;
|
||||
int rfc1510_bitstring;
|
||||
int version_flag;
|
||||
int help_flag;
|
||||
struct getargs args[] = {
|
||||
{ "encode-rfc1510-bit-string", 0, arg_flag, &rfc1510_bitstring },
|
||||
{ "decode-dce-ber", 0, arg_flag, &dce_fix },
|
||||
{ "preserve-binary", 0, arg_strings, &preserve },
|
||||
{ "version", 0, arg_flag, &version_flag },
|
||||
{ "help", 0, arg_flag, &help_flag }
|
||||
};
|
||||
@@ -53,12 +71,14 @@ usage(int code)
|
||||
exit(code);
|
||||
}
|
||||
|
||||
int error_flag;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
const char *file;
|
||||
const char *name = NULL;
|
||||
char *file;
|
||||
char *name = NULL;
|
||||
int optidx = 0;
|
||||
|
||||
setprogname(argv[0]);
|
||||
@@ -79,12 +99,21 @@ main(int argc, char **argv)
|
||||
yyin = fopen (file, "r");
|
||||
if (yyin == NULL)
|
||||
err (1, "open %s", file);
|
||||
name = argv[optidx + 1];
|
||||
if (argc == optidx + 1) {
|
||||
char *p;
|
||||
name = estrdup(file);
|
||||
p = strrchr(name, '.');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
} else
|
||||
name = argv[optidx + 1];
|
||||
}
|
||||
|
||||
init_generate (file, name);
|
||||
initsym ();
|
||||
ret = yyparse ();
|
||||
if(ret != 0 || error_flag != 0)
|
||||
exit(1);
|
||||
close_generate ();
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
936
lib/asn1/parse.y
936
lib/asn1/parse.y
File diff suppressed because it is too large
Load Diff
79
lib/asn1/pkcs12.asn1
Normal file
79
lib/asn1/pkcs12.asn1
Normal file
@@ -0,0 +1,79 @@
|
||||
-- $Id$ --
|
||||
|
||||
PKCS12 DEFINITIONS ::=
|
||||
|
||||
BEGIN
|
||||
|
||||
IMPORTS ContentInfo FROM cms
|
||||
DigestInfo FROM rfc2459
|
||||
heim_any, heim_any_set FROM heim;
|
||||
|
||||
-- The PFX PDU
|
||||
|
||||
id-pkcs-12 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
||||
rsadsi(113549) pkcs(1) pkcs-12(12) }
|
||||
|
||||
id-pkcs-12PbeIds OBJECT IDENTIFIER ::= { id-pkcs-12 1}
|
||||
id-pbeWithSHAAnd128BitRC4 OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 1}
|
||||
id-pbeWithSHAAnd40BitRC4 OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 2}
|
||||
id-pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 3}
|
||||
id-pbeWithSHAAnd2-KeyTripleDES-CBC OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 4}
|
||||
id-pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 5}
|
||||
id-pbewithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 6}
|
||||
|
||||
id-pkcs12-bagtypes OBJECT IDENTIFIER ::= { id-pkcs-12 10 1}
|
||||
|
||||
id-pkcs12-keyBag OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 1 }
|
||||
id-pkcs12-pkcs8ShroudedKeyBag OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 2 }
|
||||
id-pkcs12-certBag OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 3 }
|
||||
id-pkcs12-crlBag OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 4 }
|
||||
id-pkcs12-secretBag OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 5 }
|
||||
id-pkcs12-safeContentsBag OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 6 }
|
||||
|
||||
|
||||
PKCS12-MacData ::= SEQUENCE {
|
||||
mac DigestInfo,
|
||||
macSalt OCTET STRING,
|
||||
iterations INTEGER OPTIONAL
|
||||
}
|
||||
|
||||
PKCS12-PFX ::= SEQUENCE {
|
||||
version INTEGER,
|
||||
authSafe ContentInfo,
|
||||
macData PKCS12-MacData OPTIONAL
|
||||
}
|
||||
|
||||
PKCS12-AuthenticatedSafe ::= SEQUENCE OF ContentInfo
|
||||
-- Data if unencrypted
|
||||
-- EncryptedData if password-encrypted
|
||||
-- EnvelopedData if public key-encrypted
|
||||
|
||||
PKCS12-Attribute ::= SEQUENCE {
|
||||
attrId OBJECT IDENTIFIER,
|
||||
attrValues -- SET OF -- heim_any_set
|
||||
}
|
||||
|
||||
PKCS12-Attributes ::= SET OF PKCS12-Attribute
|
||||
|
||||
PKCS12-SafeBag ::= SEQUENCE {
|
||||
bagId OBJECT IDENTIFIER,
|
||||
bagValue [0] heim_any,
|
||||
bagAttributes PKCS12-Attributes OPTIONAL
|
||||
}
|
||||
|
||||
PKCS12-SafeContents ::= SEQUENCE OF PKCS12-SafeBag
|
||||
|
||||
PKCS12-CertBag ::= SEQUENCE {
|
||||
certType OBJECT IDENTIFIER,
|
||||
certValue [0] heim_any
|
||||
}
|
||||
|
||||
PKCS12-PBEParams ::= SEQUENCE {
|
||||
salt OCTET STRING,
|
||||
iterations INTEGER (0..4294967295) OPTIONAL
|
||||
}
|
||||
|
||||
-- KeyBag ::= PrivateKeyInfo
|
||||
-- PKCS8ShroudedKeyBag ::= EncryptedPrivateKeyInfo
|
||||
|
||||
END
|
30
lib/asn1/pkcs8.asn1
Normal file
30
lib/asn1/pkcs8.asn1
Normal file
@@ -0,0 +1,30 @@
|
||||
-- $Id$ --
|
||||
|
||||
PKCS8 DEFINITIONS ::=
|
||||
|
||||
BEGIN
|
||||
|
||||
IMPORTS Attribute, AlgorithmIdentifier FROM rfc2459
|
||||
heim_any, heim_any_set FROM heim;
|
||||
|
||||
PKCS8PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
|
||||
PKCS8PrivateKey ::= OCTET STRING
|
||||
|
||||
PKCS8Attributes ::= SET OF Attribute
|
||||
|
||||
PKCS8PrivateKeyInfo ::= SEQUENCE {
|
||||
version INTEGER,
|
||||
privateKeyAlgorithm PKCS8PrivateKeyAlgorithmIdentifier,
|
||||
privateKey PKCS8PrivateKey,
|
||||
attributes [0] IMPLICIT PKCS8Attributes OPTIONAL
|
||||
}
|
||||
|
||||
PKCS8EncryptedData ::= OCTET STRING
|
||||
|
||||
PKCS8EncryptedPrivateKeyInfo ::= SEQUENCE {
|
||||
encryptionAlgorithm AlgorithmIdentifier,
|
||||
encryptedData PKCS8EncryptedData
|
||||
}
|
||||
|
||||
END
|
22
lib/asn1/pkcs9.asn1
Normal file
22
lib/asn1/pkcs9.asn1
Normal file
@@ -0,0 +1,22 @@
|
||||
-- $Id$ --
|
||||
|
||||
PKCS9 DEFINITIONS ::=
|
||||
|
||||
BEGIN
|
||||
|
||||
-- The PFX PDU
|
||||
|
||||
id-pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
||||
rsadsi(113549) pkcs(1) pkcs-9(9) }
|
||||
|
||||
id-pkcs-9-at-friendlyName OBJECT IDENTIFIER ::= {id-pkcs-9 20}
|
||||
id-pkcs-9-at-localKeyId OBJECT IDENTIFIER ::= {id-pkcs-9 21}
|
||||
id-pkcs-9-at-certTypes OBJECT IDENTIFIER ::= {id-pkcs-9 22}
|
||||
id-pkcs-9-at-certTypes-x509 OBJECT IDENTIFIER ::= {id-pkcs-9-at-certTypes 1}
|
||||
|
||||
PKCS9-BMPString ::= BMPString
|
||||
|
||||
PKCS9-friendlyName ::= SET OF PKCS9-BMPString
|
||||
|
||||
END
|
||||
|
@@ -1,189 +1,171 @@
|
||||
-- $Id$ --
|
||||
|
||||
PKINIT DEFINITIONS ::= BEGIN
|
||||
|
||||
IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, TypedData
|
||||
FROM krb5;
|
||||
IMPORTS SignedData, EnvelopedData FROM CMS;
|
||||
IMPORTS CertificateSerialNumber, AttributeTypeAndValue, Name FROM X509;
|
||||
IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, Checksum FROM krb5
|
||||
IssuerAndSerialNumber, ContentInfo FROM cms
|
||||
SubjectPublicKeyInfo, AlgorithmIdentifier FROM rfc2459
|
||||
heim_any FROM heim;
|
||||
|
||||
id-pkinit OBJECT IDENTIFIER ::=
|
||||
{ iso (1) org (3) dod (6) internet (1) security (5)
|
||||
kerberosv5 (2) pkinit (3) }
|
||||
|
||||
-- 3.1
|
||||
id-pkauthdata OBJECT IDENTIFIER ::= { id-pkinit 1 }
|
||||
id-pkdhkeydata OBJECT IDENTIFIER ::= { id-pkinit 2 }
|
||||
id-pkrkeydata OBJECT IDENTIFIER ::= { id-pkinit 3 }
|
||||
id-pkekuoid OBJECT IDENTIFIER ::= { id-pkinit 4 }
|
||||
id-pkkdcekuoid OBJECT IDENTIFIER ::= { id-pkinit 5 }
|
||||
|
||||
CertPrincipalName ::= SEQUENCE {
|
||||
name-type[0] INTEGER,
|
||||
name-string[1] SEQUENCE OF UTF8String
|
||||
}
|
||||
pa-pk-as-req INTEGER ::= 16
|
||||
pa-pk-as-rep INTEGER ::= 17
|
||||
|
||||
ad-initial-verified-cas INTEGER ::= 9
|
||||
|
||||
-- 3.2.2
|
||||
td-trusted-certifiers INTEGER ::= 104
|
||||
td-invalid-certificates INTEGER ::= 105
|
||||
td-dh-parameters INTEGER ::= 109
|
||||
|
||||
DHNonce ::= OCTET STRING
|
||||
|
||||
TrustedCertifiers ::= SEQUENCE OF PrincipalName
|
||||
-- X.500 name encoded as a principal name
|
||||
-- see Section 3.1
|
||||
CertificateIndex ::= INTEGER
|
||||
-- 0 = 1st certificate,
|
||||
-- (in order of encoding)
|
||||
-- 1 = 2nd certificate, etc
|
||||
|
||||
PA-PK-AS-REP ::= CHOICE {
|
||||
-- PA TYPE 15
|
||||
dhSignedData[0] SignedData,
|
||||
-- Defined in CMS and used only with
|
||||
-- Diffie-Hellman key exchange (if the
|
||||
-- client public value was present in the
|
||||
-- request).
|
||||
-- This choice MUST be supported
|
||||
-- by compliant implementations.
|
||||
encKeyPack[1] EnvelopedData
|
||||
-- Defined in CMS
|
||||
-- The temporary key is encrypted
|
||||
-- using the client public key
|
||||
-- key
|
||||
-- SignedReplyKeyPack, encrypted
|
||||
-- with the temporary key, is also
|
||||
-- included.
|
||||
}
|
||||
|
||||
|
||||
|
||||
KdcDHKeyInfo ::= SEQUENCE {
|
||||
-- used only when utilizing Diffie-Hellman
|
||||
nonce[0] INTEGER,
|
||||
-- binds responce to the request
|
||||
subjectPublicKey[2] BIT STRING
|
||||
-- Equals public exponent (g^a mod p)
|
||||
-- INTEGER encoded as payload of
|
||||
-- BIT STRING
|
||||
}
|
||||
|
||||
ReplyKeyPack ::= SEQUENCE {
|
||||
-- not used for Diffie-Hellman
|
||||
replyKey[0] EncryptionKey,
|
||||
-- used to encrypt main reply
|
||||
-- ENCTYPE is at least as strong as
|
||||
-- ENCTYPE of session key
|
||||
nonce[1] INTEGER
|
||||
-- binds response to the request
|
||||
-- must be same as the nonce
|
||||
-- passed in the PKAuthenticator
|
||||
}
|
||||
|
||||
-- subjectAltName EXTENSION ::= {
|
||||
-- SYNTAX GeneralNames
|
||||
-- IDENTIFIED BY id-ce-subjectAltName
|
||||
-- }
|
||||
|
||||
OtherName ::= SEQUENCE {
|
||||
type-id OBJECT IDENTIFIER,
|
||||
value[0] OCTET STRING
|
||||
-- value[0] EXPLICIT ANY DEFINED BY type-id
|
||||
}
|
||||
|
||||
GeneralName ::= CHOICE {
|
||||
otherName [0] OtherName,
|
||||
TrustedCA ::= SEQUENCE {
|
||||
caName [0] IMPLICIT OCTET STRING,
|
||||
certificateSerialNumber [1] INTEGER OPTIONAL,
|
||||
subjectKeyIdentifier [2] OCTET STRING OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
GeneralNames ::= SEQUENCE -- SIZE(1..MAX)
|
||||
OF GeneralName
|
||||
|
||||
KerberosName ::= SEQUENCE {
|
||||
realm[0] Realm,
|
||||
-- as defined in RFC 1510
|
||||
principalName[1] CertPrincipalName
|
||||
-- defined above
|
||||
}
|
||||
|
||||
|
||||
-- krb5 OBJECT IDENTIFIER ::= {
|
||||
-- iso (1) org (3) dod (6) internet (1) security (5) kerberosv5 (2)
|
||||
-- }
|
||||
|
||||
-- krb5PrincipalName OBJECT IDENTIFIER ::= { krb5 2 }
|
||||
|
||||
-- 3.2.1
|
||||
|
||||
|
||||
IssuerAndSerialNumber ::= SEQUENCE {
|
||||
issuer Name,
|
||||
serialNumber CertificateSerialNumber
|
||||
}
|
||||
|
||||
TrustedCas ::= CHOICE {
|
||||
principalName[0] KerberosName,
|
||||
-- as defined below
|
||||
caName[1] Name,
|
||||
-- fully qualified X.500 name
|
||||
-- as defined by X.509
|
||||
issuerAndSerial[2] IssuerAndSerialNumber
|
||||
-- Since a CA may have a number of
|
||||
-- certificates, only one of which
|
||||
-- a client trusts
|
||||
}
|
||||
|
||||
PA-PK-AS-REQ ::= SEQUENCE {
|
||||
-- PA TYPE 14
|
||||
signedAuthPack[0] SignedData,
|
||||
-- defined in CMS [11]
|
||||
-- AuthPack (below) defines the data
|
||||
-- that is signed
|
||||
trustedCertifiers[1] SEQUENCE OF TrustedCas OPTIONAL,
|
||||
-- CAs that the client trusts
|
||||
kdcCert[2] IssuerAndSerialNumber OPTIONAL,
|
||||
-- as defined in CMS [11]
|
||||
-- specifies a particular KDC
|
||||
-- certificate if the client
|
||||
-- already has it;
|
||||
encryptionCert[3] IssuerAndSerialNumber OPTIONAL
|
||||
-- For example, this may be the
|
||||
-- client's Diffie-Hellman
|
||||
-- certificate, or it may be the
|
||||
-- client's RSA encryption
|
||||
-- certificate.
|
||||
signedAuthPack [0] IMPLICIT OCTET STRING,
|
||||
trustedCertifiers [1] SEQUENCE OF TrustedCA OPTIONAL,
|
||||
kdcPkId [2] IMPLICIT OCTET STRING OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
PKAuthenticator ::= SEQUENCE {
|
||||
kdcName[0] PrincipalName,
|
||||
kdcRealm[1] Realm,
|
||||
cusec[2] INTEGER,
|
||||
-- for replay prevention as in RFC1510
|
||||
ctime[3] KerberosTime,
|
||||
-- for replay prevention as in RFC1510
|
||||
nonce[4] INTEGER
|
||||
cusec [0] INTEGER -- (0..999999) --,
|
||||
ctime [1] KerberosTime,
|
||||
nonce [2] INTEGER (0..4294967295),
|
||||
paChecksum [3] OCTET STRING,
|
||||
...
|
||||
}
|
||||
|
||||
-- This is the real definition of AlgorithmIdentifier
|
||||
-- AlgorithmIdentifier ::= SEQUENCE {
|
||||
-- algorithm ALGORITHM.&id,
|
||||
-- parameters ALGORITHM.&Type
|
||||
-- } -- as specified by the X.509 recommendation[10]
|
||||
|
||||
-- But we'll use this one instead:
|
||||
|
||||
AlgorithmIdentifier ::= SEQUENCE {
|
||||
algorithm OBJECT IDENTIFIER,
|
||||
parameters CHOICE {
|
||||
a INTEGER
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
algorithm AlgorithmIdentifier,
|
||||
-- dhKeyAgreement
|
||||
subjectPublicKey BIT STRING
|
||||
-- for DH, equals
|
||||
-- public exponent (INTEGER encoded
|
||||
-- as payload of BIT STRING)
|
||||
} -- as specified by the X.509 recommendation[10]
|
||||
|
||||
AuthPack ::= SEQUENCE {
|
||||
pkAuthenticator[0] PKAuthenticator,
|
||||
clientPublicValue[1] SubjectPublicKeyInfo OPTIONAL
|
||||
-- if client is using Diffie-Hellman
|
||||
-- (ephemeral-ephemeral only)
|
||||
pkAuthenticator [0] PKAuthenticator,
|
||||
clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL,
|
||||
supportedCMSTypes [2] SEQUENCE OF AlgorithmIdentifier OPTIONAL,
|
||||
clientDHNonce [3] DHNonce OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
TD-TRUSTED-CERTIFIERS ::= SEQUENCE OF TrustedCA
|
||||
TD-INVALID-CERTIFICATES ::= SEQUENCE OF OCTET STRING
|
||||
|
||||
KRB5PrincipalName ::= SEQUENCE {
|
||||
realm [0] Realm,
|
||||
principalName [1] PrincipalName
|
||||
}
|
||||
|
||||
AD-INITIAL-VERIFIED-CAS ::= SEQUENCE OF TrustedCA
|
||||
|
||||
|
||||
DHRepInfo ::= SEQUENCE {
|
||||
dhSignedData [0] IMPLICIT OCTET STRING,
|
||||
serverDHNonce [1] DHNonce OPTIONAL
|
||||
}
|
||||
|
||||
PA-PK-AS-REP ::= CHOICE {
|
||||
dhInfo [0] DHRepInfo,
|
||||
encKeyPack [1] IMPLICIT OCTET STRING,
|
||||
...
|
||||
}
|
||||
|
||||
KDCDHKeyInfo ::= SEQUENCE {
|
||||
subjectPublicKey [0] BIT STRING,
|
||||
nonce [1] INTEGER (0..4294967295),
|
||||
dhKeyExpiration [2] KerberosTime OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
ReplyKeyPack ::= SEQUENCE {
|
||||
replyKey [0] EncryptionKey,
|
||||
nonce [1] INTEGER (0..4294967295),
|
||||
...
|
||||
}
|
||||
|
||||
TD-DH-PARAMETERS ::= SEQUENCE OF AlgorithmIdentifier
|
||||
|
||||
|
||||
-- Windows and pk-init-19 compat glue --
|
||||
|
||||
PKAuthenticator-Win2k ::= SEQUENCE {
|
||||
kdcName [0] PrincipalName,
|
||||
kdcRealm [1] Realm,
|
||||
cusec [2] INTEGER (0..4294967295),
|
||||
ctime [3] KerberosTime,
|
||||
nonce [4] INTEGER (-2147483648..2147483647)
|
||||
}
|
||||
|
||||
AuthPack-Win2k ::= SEQUENCE {
|
||||
pkAuthenticator [0] PKAuthenticator-Win2k,
|
||||
clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL
|
||||
}
|
||||
|
||||
|
||||
PA-PK-AS-REP-Win2k ::= CHOICE {
|
||||
dhSignedData [0] IMPLICIT OCTET STRING,
|
||||
encKeyPack [1] IMPLICIT OCTET STRING
|
||||
}
|
||||
|
||||
|
||||
KDCDHKeyInfo-Win2k ::= SEQUENCE {
|
||||
nonce [0] INTEGER (-2147483648..2147483647),
|
||||
subjectPublicKey [2] BIT STRING
|
||||
}
|
||||
|
||||
TrustedCA-19 ::= CHOICE {
|
||||
caName [1] heim_any,
|
||||
issuerAndSerial [2] IssuerAndSerialNumber
|
||||
}
|
||||
|
||||
PA-PK-AS-REQ-19 ::= SEQUENCE { -- PAType 14
|
||||
signedAuthPack [0] ContentInfo, -- AuthPack
|
||||
trustedCertifiers [1] SEQUENCE OF TrustedCA-19 OPTIONAL,
|
||||
kdcCert [2] IssuerAndSerialNumber OPTIONAL,
|
||||
encryptionCert [3] IssuerAndSerialNumber OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
PA-PK-AS-REQ-Win2k ::= SEQUENCE {
|
||||
signed-auth-pack [0] IMPLICIT OCTET STRING,
|
||||
trusted-certifiers [2] SEQUENCE OF TrustedCA-19 OPTIONAL,
|
||||
kdc-cert [3] IMPLICIT OCTET STRING OPTIONAL,
|
||||
encryption-cert [4] IMPLICIT OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
PKAuthenticator-19 ::= SEQUENCE {
|
||||
cusec [0] INTEGER (0..4294967295),
|
||||
ctime [1] KerberosTime,
|
||||
nonce [2] INTEGER (0..4294967295),
|
||||
paChecksum [3] Checksum,
|
||||
...
|
||||
}
|
||||
|
||||
AuthPack-19 ::= SEQUENCE {
|
||||
pkAuthenticator [0] PKAuthenticator-19,
|
||||
clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL
|
||||
}
|
||||
|
||||
PA-PK-AS-REP-19 ::= CHOICE {
|
||||
dhSignedData [0] ContentInfo,
|
||||
encKeyPack [1] ContentInfo,
|
||||
...
|
||||
}
|
||||
|
||||
ReplyKeyPack-19 ::= SEQUENCE {
|
||||
replyKey [0] EncryptionKey,
|
||||
nonce [1] INTEGER (0..4294967295),
|
||||
...
|
||||
}
|
||||
|
||||
END
|
||||
|
@@ -1,21 +1,291 @@
|
||||
-- $Id$ --
|
||||
-- Definitions from rfc2459/rfc3280
|
||||
|
||||
RFC2459 DEFINITIONS ::= BEGIN
|
||||
|
||||
AttributeType ::= OBJECT-IDENTIFIER
|
||||
IMPORTS heim_any FROM heim;
|
||||
|
||||
AttributeValue ::= OCTET STRING --ANY DEFINED BY AttributeType
|
||||
|
||||
AttributeTypeAndValue ::= SEQUENCE {
|
||||
type AttributeType,
|
||||
value AttributeValue
|
||||
Version ::= INTEGER {
|
||||
rfc3280_version_1(0),
|
||||
rfc3280_version_2(1),
|
||||
rfc3280_version_3(2)
|
||||
}
|
||||
|
||||
RelativeDistinguishedName ::= --SET
|
||||
SEQUENCE OF AttributeTypeAndValue
|
||||
id-pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
||||
rsadsi(113549) pkcs(1) 1 }
|
||||
id-pkcs1-rsaEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 1 }
|
||||
id-pkcs1-md2WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 2 }
|
||||
id-pkcs1-md5WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 4 }
|
||||
id-pkcs1-sha1WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 5 }
|
||||
|
||||
id-pkcs-2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
||||
rsadsi(113549) pkcs(1) 2 }
|
||||
id-pkcs2-md2 OBJECT IDENTIFIER ::= { id-pkcs-2 2 }
|
||||
id-pkcs2-md4 OBJECT IDENTIFIER ::= { id-pkcs-2 4 }
|
||||
id-pkcs2-md5 OBJECT IDENTIFIER ::= { id-pkcs-2 5 }
|
||||
|
||||
id-pkcs-3 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
||||
rsadsi(113549) pkcs(1) 3 }
|
||||
|
||||
id-pkcs3-rc2-cbc OBJECT IDENTIFIER ::= { id-pkcs-3 2 }
|
||||
id-pkcs3-rc4 OBJECT IDENTIFIER ::= { id-pkcs-3 4 }
|
||||
id-pkcs3-des-ede3-cbc OBJECT IDENTIFIER ::= { id-pkcs-3 7 }
|
||||
|
||||
id-rsadsi-encalg OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
||||
rsadsi(113549) 3 }
|
||||
|
||||
id-rsadsi-des-ede3-cbc OBJECT IDENTIFIER ::= { id-rsadsi-encalg 7 }
|
||||
|
||||
id-secsig-sha-1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
|
||||
oiw(14) secsig(3) algorithm(2) 26 }
|
||||
|
||||
id-nit-aes-algs OBJECT IDENTIFIER ::= {
|
||||
joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3)
|
||||
nistAlgorithm(4) 1 }
|
||||
|
||||
id-aes-128-cbc OBJECT IDENTIFIER ::= { id-nit-aes-algs 2 }
|
||||
id-aes-192-cbc OBJECT IDENTIFIER ::= { id-nit-aes-algs 22 }
|
||||
id-aes-256-cbc OBJECT IDENTIFIER ::= { id-nit-aes-algs 42 }
|
||||
|
||||
id-dhpublicnumber OBJECT IDENTIFIER ::= {
|
||||
iso(1) member-body(2) us(840) ansi-x942(10046)
|
||||
number-type(2) 1 }
|
||||
|
||||
id-x509-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
|
||||
|
||||
AlgorithmIdentifier ::= SEQUENCE {
|
||||
algorithm OBJECT IDENTIFIER,
|
||||
parameters heim_any OPTIONAL
|
||||
}
|
||||
|
||||
AttributeType ::= OBJECT IDENTIFIER
|
||||
|
||||
AttributeValue ::= heim_any
|
||||
|
||||
TeletexStringx ::= [UNIVERSAL 20] IMPLICIT OCTET STRING
|
||||
|
||||
DirectoryString ::= CHOICE {
|
||||
ia5String IA5String,
|
||||
teletexString TeletexStringx,
|
||||
printableString PrintableString,
|
||||
universalString UniversalString,
|
||||
utf8String UTF8String,
|
||||
bmpString BMPString
|
||||
}
|
||||
|
||||
Attribute ::= SEQUENCE {
|
||||
type AttributeType,
|
||||
value AttributeValue
|
||||
}
|
||||
|
||||
AttributeTypeAndValue ::= SEQUENCE {
|
||||
type AttributeType,
|
||||
value DirectoryString
|
||||
}
|
||||
|
||||
RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
|
||||
|
||||
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
|
||||
|
||||
Name ::= CHOICE { -- RFC2459
|
||||
x RDNSequence
|
||||
Name ::= CHOICE {
|
||||
rdnSequence RDNSequence
|
||||
}
|
||||
|
||||
CertificateSerialNumber ::= INTEGER
|
||||
|
||||
Time ::= CHOICE {
|
||||
utcTime UTCTime,
|
||||
generalTime GeneralizedTime
|
||||
}
|
||||
|
||||
Validity ::= SEQUENCE {
|
||||
notBefore Time,
|
||||
notAfter Time
|
||||
}
|
||||
|
||||
UniqueIdentifier ::= BIT STRING
|
||||
|
||||
SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
algorithm AlgorithmIdentifier,
|
||||
subjectPublicKey BIT STRING
|
||||
}
|
||||
|
||||
Extension ::= SEQUENCE {
|
||||
extnID OBJECT IDENTIFIER,
|
||||
critical BOOLEAN OPTIONAL, -- DEFAULT FALSE XXX
|
||||
extnValue OCTET STRING
|
||||
}
|
||||
|
||||
Extensions ::= SEQUENCE OF Extension -- SIZE (1..MAX)
|
||||
|
||||
TBSCertificate ::= SEQUENCE {
|
||||
version [0] Version OPTIONAL, -- EXPLICIT nnn DEFAULT 1,
|
||||
serialNumber CertificateSerialNumber,
|
||||
signature AlgorithmIdentifier,
|
||||
issuer Name,
|
||||
validity Validity,
|
||||
subject Name,
|
||||
subjectPublicKeyInfo SubjectPublicKeyInfo,
|
||||
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
|
||||
-- If present, version shall be v2 or v3
|
||||
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
|
||||
-- If present, version shall be v2 or v3
|
||||
extensions [3] EXPLICIT Extensions OPTIONAL
|
||||
-- If present, version shall be v3
|
||||
}
|
||||
|
||||
Certificate ::= SEQUENCE {
|
||||
tbsCertificate TBSCertificate,
|
||||
signatureAlgorithm AlgorithmIdentifier,
|
||||
signatureValue BIT STRING
|
||||
}
|
||||
|
||||
Certificates ::= SEQUENCE OF Certificate
|
||||
|
||||
ValidationParms ::= SEQUENCE {
|
||||
seed BIT STRING,
|
||||
pgenCounter INTEGER
|
||||
}
|
||||
|
||||
DomainParameters ::= SEQUENCE {
|
||||
p INTEGER, -- odd prime, p=jq +1
|
||||
g INTEGER, -- generator, g
|
||||
q INTEGER, -- factor of p-1
|
||||
j INTEGER OPTIONAL, -- subgroup factor
|
||||
validationParms ValidationParms OPTIONAL -- ValidationParms
|
||||
}
|
||||
|
||||
OtherName ::= SEQUENCE {
|
||||
type-id OBJECT IDENTIFIER,
|
||||
value [0] EXPLICIT heim_any
|
||||
}
|
||||
|
||||
GeneralName ::= CHOICE {
|
||||
otherName [0] OtherName,
|
||||
rfc822Name [1] IA5String,
|
||||
dNSName [2] IA5String,
|
||||
-- x400Address [3] ORAddress,--
|
||||
directoryName [4] Name,
|
||||
-- ediPartyName [5] EDIPartyName, --
|
||||
uniformResourceIdentifier [6] IA5String,
|
||||
iPAddress [7] OCTET STRING,
|
||||
registeredID [8] OBJECT IDENTIFIER
|
||||
}
|
||||
|
||||
GeneralNames ::= SEQUENCE -- SIZE (1..MAX) -- OF GeneralName
|
||||
|
||||
id-x509-ce-keyUsage OBJECT IDENTIFIER ::= { id-x509-ce 15 }
|
||||
|
||||
KeyUsage ::= BIT STRING {
|
||||
digitalSignature (0),
|
||||
nonRepudiation (1),
|
||||
keyEncipherment (2),
|
||||
dataEncipherment (3),
|
||||
keyAgreement (4),
|
||||
keyCertSign (5),
|
||||
cRLSign (6),
|
||||
encipherOnly (7),
|
||||
decipherOnly (8)
|
||||
}
|
||||
|
||||
id-x509-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-x509-ce 35 }
|
||||
|
||||
KeyIdentifier ::= OCTET STRING
|
||||
|
||||
AuthorityKeyIdentifier ::= SEQUENCE {
|
||||
keyIdentifier [0] IMPLICIT OCTET STRING OPTIONAL,
|
||||
authorityCertIssuer [1] IMPLICIT heim_any OPTIONAL,
|
||||
authorityCertSerialNumber [2] IMPLICIT INTEGER OPTIONAL
|
||||
}
|
||||
|
||||
id-x509-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-x509-ce 14 }
|
||||
|
||||
SubjectKeyIdentifier ::= KeyIdentifier
|
||||
|
||||
id-x509-ce-basicConstraints OBJECT IDENTIFIER ::= { id-x509-ce 19 }
|
||||
|
||||
BasicConstraints ::= SEQUENCE {
|
||||
cA BOOLEAN OPTIONAL -- DEFAULT FALSE --,
|
||||
pathLenConstraint INTEGER (0..4294967295) OPTIONAL
|
||||
}
|
||||
|
||||
id-x509-ce-nameConstraints OBJECT IDENTIFIER ::= { id-x509-ce 30 }
|
||||
|
||||
BaseDistance ::= INTEGER -- (0..MAX) --
|
||||
|
||||
GeneralSubtree ::= SEQUENCE {
|
||||
base GeneralName,
|
||||
minimum [0] BaseDistance OPTIONAL -- DEFAULT 0 --,
|
||||
maximum [1] BaseDistance OPTIONAL
|
||||
}
|
||||
|
||||
GeneralSubtrees ::= SEQUENCE -- SIZE (1..MAX) -- OF GeneralSubtree
|
||||
|
||||
NameConstraints ::= SEQUENCE {
|
||||
permittedSubtrees [0] GeneralSubtrees OPTIONAL,
|
||||
excludedSubtrees [1] GeneralSubtrees OPTIONAL
|
||||
}
|
||||
|
||||
id-x509-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= { id-x509-ce 16 }
|
||||
id-x509-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-x509-ce 32 }
|
||||
id-x509-ce-policyMappings OBJECT IDENTIFIER ::= { id-x509-ce 33 }
|
||||
id-x509-ce-subjectAltName OBJECT IDENTIFIER ::= { id-x509-ce 17 }
|
||||
id-x509-ce-issuerAltName OBJECT IDENTIFIER ::= { id-x509-ce 18 }
|
||||
id-x509-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-x509-ce 9 }
|
||||
id-x509-ce-policyConstraints OBJECT IDENTIFIER ::= { id-x509-ce 36 }
|
||||
id-x509-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-x509-ce 37}
|
||||
id-x509-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-x509-ce 31 }
|
||||
id-x509-ce-cRLNumber OBJECT IDENTIFIER ::= { id-x509-ce 20 }
|
||||
id-x509-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-x509-ce 27 }
|
||||
id-x509-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-x509-ce 28 }
|
||||
id-x509-ce-cRLReasons OBJECT IDENTIFIER ::= { id-x509-ce 21 }
|
||||
id-x509-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-x509-ce 23 }
|
||||
id-x509-ce-invalidityDate OBJECT IDENTIFIER ::= { id-x509-ce 24 }
|
||||
id-x509-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-x509-ce 29 }
|
||||
id-x509-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-x509-ce 54 }
|
||||
id-x509-ce-freshestCRL OBJECT IDENTIFIER ::= { id-x509-ce 46 }
|
||||
|
||||
-- rfc3279
|
||||
|
||||
DSASigValue ::= SEQUENCE {
|
||||
r INTEGER,
|
||||
s INTEGER
|
||||
}
|
||||
|
||||
DSAPublicKey ::= INTEGER
|
||||
|
||||
DSAParams ::= SEQUENCE {
|
||||
p INTEGER,
|
||||
q INTEGER,
|
||||
g INTEGER
|
||||
}
|
||||
|
||||
-- really pkcs1
|
||||
|
||||
RSAPublicKey ::= SEQUENCE {
|
||||
modulus INTEGER, -- n
|
||||
publicExponent INTEGER -- e
|
||||
}
|
||||
|
||||
DigestInfo ::= SEQUENCE {
|
||||
digestAlgorithm AlgorithmIdentifier,
|
||||
digest OCTET STRING
|
||||
}
|
||||
|
||||
-- some ms ext
|
||||
|
||||
-- szOID_ENROLL_CERTTYPE_EXTENSION "1.3.6.1.4.1.311.20.2" is Encoded as a
|
||||
|
||||
-- UNICODESTRING (0x1E tag)
|
||||
|
||||
-- szOID_CERTIFICATE_TEMPLATE "1.3.6.1.4.1.311.21.7" is Encoded as:
|
||||
|
||||
-- TemplateVersion ::= INTEGER (0..4294967295)
|
||||
|
||||
-- CertificateTemplate ::= SEQUENCE {
|
||||
-- templateID OBJECT IDENTIFIER,
|
||||
-- templateMajorVersion TemplateVersion,
|
||||
-- templateMinorVersion TemplateVersion OPTIONAL
|
||||
-- }
|
||||
|
||||
END
|
@@ -168,25 +168,25 @@ Request ::= [ APPLICATION 0 ] SEQUENCE {
|
||||
languages[2] SEQUENCE OF Language-Tag OPTIONAL,
|
||||
targ-name[3] PrincipalName OPTIONAL,
|
||||
targ-realm[4] Realm OPTIONAL,
|
||||
-- operation[5] Op-Req,
|
||||
operation[5] Op-Req,
|
||||
...
|
||||
}
|
||||
|
||||
Responce ::= [ APPLICATION 1 ] SEQUENCE {
|
||||
Response ::= [ APPLICATION 1 ] SEQUENCE {
|
||||
pvno-major[0] INTEGER DEFAULT 2,
|
||||
pvno-minor[1] INTEGER DEFAULT 0,
|
||||
language[2] Language-Tag DEFAULT "i-default",
|
||||
-- result[3] Op-rep OPTIONAL,
|
||||
result[3] Op-rep OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
Error-Responce ::= [ APPLICATION 2 ] SEQUENCE {
|
||||
Error-Response ::= [ APPLICATION 2 ] SEQUENCE {
|
||||
pvno-major[0] INTEGER DEFAULT 2,
|
||||
pvno-minor[1] INTEGER DEFAULT 0,
|
||||
language[2] Language-Tag DEFAULT "i-default",
|
||||
error-code[3] ProtocolErrorCode,
|
||||
help-text[4] UTF8String OPTIONAL,
|
||||
-- op-error[5] Op-error OP-ERROR,
|
||||
op-error[5] Op-error OP-ERROR,
|
||||
...
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2001 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -32,59 +32,79 @@
|
||||
*/
|
||||
|
||||
#include "gen_locl.h"
|
||||
#include "lex.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
static Hashtab *htab;
|
||||
|
||||
static int
|
||||
cmp (void *a, void *b)
|
||||
cmp(void *a, void *b)
|
||||
{
|
||||
Symbol *s1 = (Symbol *)a;
|
||||
Symbol *s2 = (Symbol *)b;
|
||||
Symbol *s1 = (Symbol *) a;
|
||||
Symbol *s2 = (Symbol *) b;
|
||||
|
||||
return strcmp (s1->name, s2->name);
|
||||
return strcmp(s1->name, s2->name);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
hash (void *a)
|
||||
hash(void *a)
|
||||
{
|
||||
Symbol *s = (Symbol *)a;
|
||||
Symbol *s = (Symbol *) a;
|
||||
|
||||
return hashjpw (s->name);
|
||||
return hashjpw(s->name);
|
||||
}
|
||||
|
||||
void
|
||||
initsym (void)
|
||||
initsym(void)
|
||||
{
|
||||
htab = hashtabnew (101, cmp, hash);
|
||||
htab = hashtabnew(101, cmp, hash);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
output_name (char *s)
|
||||
output_name(char *s)
|
||||
{
|
||||
char *p;
|
||||
char *p;
|
||||
|
||||
for (p = s; *p; ++p)
|
||||
if (*p == '-')
|
||||
*p = '_';
|
||||
for (p = s; *p; ++p)
|
||||
if (*p == '-')
|
||||
*p = '_';
|
||||
}
|
||||
|
||||
Symbol*
|
||||
addsym (char *name)
|
||||
Symbol *
|
||||
addsym(char *name)
|
||||
{
|
||||
Symbol key, *s;
|
||||
Symbol key, *s;
|
||||
|
||||
key.name = name;
|
||||
s = (Symbol *)hashtabsearch (htab, (void *)&key);
|
||||
if (s == NULL) {
|
||||
s = (Symbol *)malloc (sizeof (*s));
|
||||
s->name = name;
|
||||
s->gen_name = strdup(name);
|
||||
output_name (s->gen_name);
|
||||
s->stype = SUndefined;
|
||||
hashtabadd (htab, s);
|
||||
}
|
||||
return s;
|
||||
key.name = name;
|
||||
s = (Symbol *) hashtabsearch(htab, (void *) &key);
|
||||
if (s == NULL) {
|
||||
s = (Symbol *) emalloc(sizeof(*s));
|
||||
s->name = name;
|
||||
s->gen_name = estrdup(name);
|
||||
output_name(s->gen_name);
|
||||
s->stype = SUndefined;
|
||||
hashtabadd(htab, s);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static int
|
||||
checkfunc(void *ptr, void *arg)
|
||||
{
|
||||
Symbol *s = ptr;
|
||||
if (s->stype == SUndefined) {
|
||||
error_message("%s is still undefined\n", s->name);
|
||||
*(int *) arg = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
checkundefined(void)
|
||||
{
|
||||
int f = 0;
|
||||
hashtabforeach(htab, checkfunc, &f);
|
||||
return f;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2001 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -36,59 +36,104 @@
|
||||
#ifndef _SYMBOL_H
|
||||
#define _SYMBOL_H
|
||||
|
||||
#include "asn1_queue.h"
|
||||
|
||||
enum typetype {
|
||||
TApplication,
|
||||
TBitString,
|
||||
TBoolean,
|
||||
TChoice,
|
||||
TEnumerated,
|
||||
TGeneralString,
|
||||
TGeneralizedTime,
|
||||
TIA5String,
|
||||
TInteger,
|
||||
TNull,
|
||||
TOID,
|
||||
TOctetString,
|
||||
TPrintableString,
|
||||
TSequence,
|
||||
TSequenceOf,
|
||||
TSet,
|
||||
TSetOf,
|
||||
TTag,
|
||||
TType,
|
||||
TUInteger,
|
||||
TUTF8String
|
||||
TUTCTime,
|
||||
TUTF8String,
|
||||
TBMPString,
|
||||
TUniversalString
|
||||
};
|
||||
|
||||
typedef enum typetype Typetype;
|
||||
|
||||
struct type;
|
||||
|
||||
struct value {
|
||||
enum { booleanvalue,
|
||||
nullvalue,
|
||||
integervalue,
|
||||
stringvalue,
|
||||
objectidentifiervalue
|
||||
} type;
|
||||
union {
|
||||
int booleanvalue;
|
||||
int integervalue;
|
||||
char *stringvalue;
|
||||
struct objid *objectidentifiervalue;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct member {
|
||||
char *name;
|
||||
char *gen_name;
|
||||
int val;
|
||||
int optional;
|
||||
struct type *type;
|
||||
struct member *next, *prev;
|
||||
char *defval;
|
||||
char *name;
|
||||
char *gen_name;
|
||||
char *label;
|
||||
int val;
|
||||
int optional;
|
||||
int ellipsis;
|
||||
struct type *type;
|
||||
ASN1_TAILQ_ENTRY(member) members;
|
||||
struct value *defval;
|
||||
};
|
||||
|
||||
typedef struct member Member;
|
||||
|
||||
ASN1_TAILQ_HEAD(memhead, member);
|
||||
|
||||
struct symbol;
|
||||
|
||||
struct tagtype {
|
||||
int tagclass;
|
||||
int tagvalue;
|
||||
enum { TE_IMPLICIT, TE_EXPLICIT } tagenv;
|
||||
};
|
||||
|
||||
struct range {
|
||||
int min;
|
||||
int max;
|
||||
};
|
||||
|
||||
struct type {
|
||||
Typetype type;
|
||||
int application;
|
||||
Member *members;
|
||||
struct type *subtype;
|
||||
struct symbol *symbol;
|
||||
Typetype type;
|
||||
struct memhead *members;
|
||||
struct symbol *symbol;
|
||||
struct type *subtype;
|
||||
struct tagtype tag;
|
||||
struct range *range;
|
||||
};
|
||||
|
||||
typedef struct type Type;
|
||||
|
||||
struct objid {
|
||||
const char *label;
|
||||
int value;
|
||||
struct objid *next;
|
||||
};
|
||||
|
||||
struct symbol {
|
||||
char *name;
|
||||
char *gen_name;
|
||||
enum { SUndefined, SConstant, Stype } stype;
|
||||
int constant;
|
||||
Type *type;
|
||||
char *name;
|
||||
char *gen_name;
|
||||
enum { SUndefined, SValue, Stype } stype;
|
||||
struct value *value;
|
||||
Type *type;
|
||||
};
|
||||
|
||||
typedef struct symbol Symbol;
|
||||
@@ -96,4 +141,5 @@ typedef struct symbol Symbol;
|
||||
void initsym (void);
|
||||
Symbol *addsym (char *);
|
||||
void output_name (char *);
|
||||
int checkundefined(void);
|
||||
#endif
|
||||
|
30
lib/asn1/test.asn1
Normal file
30
lib/asn1/test.asn1
Normal file
@@ -0,0 +1,30 @@
|
||||
-- $Id$ --
|
||||
|
||||
TEST DEFINITIONS ::=
|
||||
|
||||
BEGIN
|
||||
|
||||
TESTLargeTag ::= SEQUENCE {
|
||||
foo[127] INTEGER (-2147483648..2147483647)
|
||||
}
|
||||
|
||||
TESTSeq ::= SEQUENCE {
|
||||
tag0[0] INTEGER (-2147483648..2147483647),
|
||||
tag1[1] TESTLargeTag,
|
||||
tagless INTEGER (-2147483648..2147483647),
|
||||
tag3[2] INTEGER (-2147483648..2147483647)
|
||||
}
|
||||
|
||||
TESTChoice1 ::= CHOICE {
|
||||
i1[1] INTEGER (-2147483648..2147483647),
|
||||
i2[2] INTEGER (-2147483648..2147483647),
|
||||
...
|
||||
}
|
||||
|
||||
TESTChoice2 ::= CHOICE {
|
||||
i1[1] INTEGER (-2147483648..2147483647),
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
END
|
14
lib/asn1/test.gen
Normal file
14
lib/asn1/test.gen
Normal file
@@ -0,0 +1,14 @@
|
||||
# $Id$
|
||||
# Sample for TESTSeq in test.asn1
|
||||
#
|
||||
|
||||
UNIV CONS Sequence 23
|
||||
CONTEXT CONS 0 3
|
||||
UNIV PRIM Integer 1 01
|
||||
CONTEXT CONS 1 8
|
||||
UNIV CONS Sequence 6
|
||||
CONTEXT CONS 127 3
|
||||
UNIV PRIM Integer 1 01
|
||||
UNIV PRIM Integer 1 01
|
||||
CONTEXT CONS 2 3
|
||||
UNIV PRIM Integer 1 01
|
@@ -1,23 +1,79 @@
|
||||
-- $Id$ --
|
||||
|
||||
X509 DEFINITIONS ::= BEGIN
|
||||
|
||||
CertificateSerialNumber ::= INTEGER -- X.509 '97
|
||||
IMPORTS heim_any FROM heim;
|
||||
|
||||
AttributeType ::= OBJECT-IDENTIFIER
|
||||
Version ::= INTEGER -- { v1(0), v2(1), v3(2) } --
|
||||
|
||||
AttributeValue ::= OCTET STRING --ANY DEFINED BY AttributeType
|
||||
AlgorithmIdentifier ::= OBJECT IDENTIFIER
|
||||
|
||||
AttributeTypeAndValue ::= SEQUENCE {
|
||||
type AttributeType,
|
||||
value AttributeValue
|
||||
AttributeType ::= OBJECT IDENTIFIER
|
||||
|
||||
AttributeValue ::= heim_any
|
||||
|
||||
Attribute ::= SEQUENCE {
|
||||
type AttributeType,
|
||||
value AttributeValue
|
||||
}
|
||||
|
||||
RelativeDistinguishedName ::= --SET
|
||||
SEQUENCE OF AttributeTypeAndValue
|
||||
RelativeDistinguishedName ::= SET OF Attribute
|
||||
|
||||
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
|
||||
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
|
||||
|
||||
Name ::= CHOICE { -- RFC2459
|
||||
x RDNSequence
|
||||
DistinguishedName ::= RDNSequence
|
||||
|
||||
Name ::= CHOICE { -- only one possibility for now --
|
||||
rdnSequence RDNSequence
|
||||
}
|
||||
|
||||
CertificateSerialNumber ::= INTEGER
|
||||
|
||||
Time ::= CHOICE {
|
||||
utcTime UTCTime,
|
||||
generalTime GeneralizedTime
|
||||
}
|
||||
|
||||
Validity ::= SEQUENCE {
|
||||
notBefore Time,
|
||||
notAfter Time
|
||||
}
|
||||
|
||||
UniqueIdentifier ::= BIT STRING
|
||||
|
||||
SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
algorithm AlgorithmIdentifier,
|
||||
subjectPublicKey BIT STRING
|
||||
}
|
||||
|
||||
Extension ::= SEQUENCE {
|
||||
extnID OBJECT IDENTIFIER,
|
||||
critical BOOLEAN DEFAULT FALSE,
|
||||
extnValue OCTET STRING
|
||||
}
|
||||
|
||||
Extensions ::= SEQUENCE OF Extension -- SIZE (1..MAX)
|
||||
|
||||
TBSCertificate ::= SEQUENCE {
|
||||
version [0] EXPLICIT Version DEFAULT 1,
|
||||
serialNumber CertificateSerialNumber,
|
||||
signature AlgorithmIdentifier,
|
||||
issuer Name,
|
||||
validity Validity,
|
||||
subject Name,
|
||||
subjectPublicKeyInfo SubjectPublicKeyInfo,
|
||||
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
|
||||
-- If present, version shall be v2 or v3
|
||||
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
|
||||
-- If present, version shall be v2 or v3
|
||||
extensions [3] EXPLICIT Extensions OPTIONAL
|
||||
-- If present, version shall be v3
|
||||
}
|
||||
|
||||
Certificate ::= SEQUENCE {
|
||||
tbsCertificate TBSCertificate,
|
||||
signatureAlgorithm AlgorithmIdentifier,
|
||||
signatureValue BIT STRING
|
||||
}
|
||||
|
||||
END
|
Reference in New Issue
Block a user