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:
Love Hörnquist Åstrand
2005-07-12 06:27:42 +00:00
parent bed557d8e7
commit b838707d0e
48 changed files with 7670 additions and 2442 deletions

141
lib/asn1/CMS.asn1 Normal file
View 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
View 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

View File

@@ -2,98 +2,329 @@
include $(top_srcdir)/Makefile.am.common include $(top_srcdir)/Makefile.am.common
YFLAGS = -d YFLAGS = -dt
lib_LTLIBRARIES = libasn1.la 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 = \ BUILT_SOURCES = \
$(gen_files:.x=.c) \ $(gen_files_rfc2459:.x=.c) \
asn1_err.h \ $(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 asn1_err.c
gen_files = \ gen_files_k5 = \
asn1_AD_AND_OR.x \ asn1_AD_AND_OR.x \
asn1_AD_IF_RELEVANT.x \ asn1_AD_IF_RELEVANT.x \
asn1_AD_KDCIssued.x \ asn1_AD_KDCIssued.x \
asn1_AD_MANDATORY_FOR_KDC.x \ asn1_AD_MANDATORY_FOR_KDC.x \
asn1_APOptions.x \ asn1_APOptions.x \
asn1_AP_REP.x \ asn1_AP_REP.x \
asn1_AP_REQ.x \ asn1_AP_REQ.x \
asn1_AS_REP.x \ asn1_AS_REP.x \
asn1_AS_REQ.x \ asn1_AS_REQ.x \
asn1_Authenticator.x \ asn1_AUTHDATA_TYPE.x \
asn1_AuthorizationData.x \ asn1_Authenticator.x \
asn1_AUTHDATA_TYPE.x \ asn1_AuthorizationData.x \
asn1_CBCParameter.x \ asn1_CKSUMTYPE.x \
asn1_CKSUMTYPE.x \ asn1_ChangePasswdDataMS.x \
asn1_ChangePasswdDataMS.x \ asn1_Checksum.x \
asn1_Checksum.x \ asn1_ENCTYPE.x \
asn1_ENCTYPE.x \ asn1_ETYPE_INFO.x \
asn1_ETYPE_INFO.x \ asn1_ETYPE_INFO2.x \
asn1_ETYPE_INFO2.x \ asn1_ETYPE_INFO2_ENTRY.x \
asn1_ETYPE_INFO2_ENTRY.x \ asn1_ETYPE_INFO_ENTRY.x \
asn1_ETYPE_INFO_ENTRY.x \ asn1_EncAPRepPart.x \
asn1_EncAPRepPart.x \ asn1_EncASRepPart.x \
asn1_EncASRepPart.x \ asn1_EncKDCRepPart.x \
asn1_EncKDCRepPart.x \ asn1_EncKrbCredPart.x \
asn1_EncKrbCredPart.x \ asn1_EncKrbPrivPart.x \
asn1_EncKrbPrivPart.x \ asn1_EncTGSRepPart.x \
asn1_EncTGSRepPart.x \ asn1_EncTicketPart.x \
asn1_EncTicketPart.x \ asn1_EncryptedData.x \
asn1_EncryptedData.x \ asn1_EncryptionKey.x \
asn1_EncryptionKey.x \ asn1_EtypeList.x \
asn1_EtypeList.x \ asn1_HostAddress.x \
asn1_HostAddress.x \ asn1_HostAddresses.x \
asn1_HostAddresses.x \ asn1_KDCOptions.x \
asn1_KDCOptions.x \ asn1_KDC_REP.x \
asn1_KDC_REP.x \ asn1_KDC_REQ.x \
asn1_KDC_REQ.x \ asn1_KDC_REQ_BODY.x \
asn1_KDC_REQ_BODY.x \ asn1_KRB_CRED.x \
asn1_KRB_CRED.x \ asn1_KRB_ERROR.x \
asn1_KRB_ERROR.x \ asn1_KRB_PRIV.x \
asn1_KRB_PRIV.x \ asn1_KRB_SAFE.x \
asn1_KRB_SAFE.x \ asn1_KRB_SAFE_BODY.x \
asn1_KRB_SAFE_BODY.x \ asn1_krb5int32.x \
asn1_KerberosString.x \ asn1_krb5uint32.x \
asn1_KerberosTime.x \ asn1_KerberosString.x \
asn1_KrbCredInfo.x \ asn1_KerberosTime.x \
asn1_LR_TYPE.x \ asn1_KrbCredInfo.x \
asn1_LastReq.x \ asn1_LR_TYPE.x \
asn1_MESSAGE_TYPE.x \ asn1_LastReq.x \
asn1_METHOD_DATA.x \ asn1_MESSAGE_TYPE.x \
asn1_NAME_TYPE.x \ asn1_METHOD_DATA.x \
asn1_PADATA_TYPE.x \ asn1_NAME_TYPE.x \
asn1_PA_DATA.x \ asn1_PADATA_TYPE.x \
asn1_PA_ENC_SAM_RESPONSE_ENC.x \ asn1_PA_DATA.x \
asn1_PA_ENC_TS_ENC.x \ asn1_PA_ENC_SAM_RESPONSE_ENC.x \
asn1_PA_PAC_REQUEST.x \ asn1_PA_ENC_TS_ENC.x \
asn1_PA_SAM_CHALLENGE_2.x \ asn1_PA_SAM_CHALLENGE_2.x \
asn1_PA_SAM_CHALLENGE_2_BODY.x \ asn1_PA_SAM_CHALLENGE_2_BODY.x \
asn1_PA_SAM_REDIRECT.x \ asn1_PA_SAM_REDIRECT.x \
asn1_PA_SAM_RESPONSE_2.x \ asn1_PA_SAM_RESPONSE_2.x \
asn1_PA_SAM_TYPE.x \ asn1_PA_SAM_TYPE.x \
asn1_Principal.x \ asn1_PA_PAC_REQUEST.x \
asn1_PrincipalName.x \ asn1_PROV_SRV_LOCATION.x \
asn1_RC2CBCParameter.x \ asn1_Principal.x \
asn1_Realm.x \ asn1_PrincipalName.x \
asn1_SAMFlags.x \ asn1_Realm.x \
asn1_TGS_REP.x \ asn1_SAMFlags.x \
asn1_TGS_REQ.x \ asn1_TGS_REP.x \
asn1_Ticket.x \ asn1_TGS_REQ.x \
asn1_TicketFlags.x \ asn1_TYPED_DATA.x \
asn1_TransitedEncoding.x \ asn1_Ticket.x \
asn1_UNSIGNED.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 check_PROGRAMS = check-der check-gen
TESTS = check-der check-gen TESTS = check-der check-gen
check_der_SOURCES = check-der.c check-common.c asn1_gen_SOURCES = asn1_gen.c
check_gen_SOURCES = check-gen.c check-common.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 = \ asn1_compile_SOURCES = \
gen.c \ gen.c \
@@ -110,12 +341,14 @@ asn1_compile_SOURCES = \
symbol.c symbol.c
libasn1_la_SOURCES = \ libasn1_la_SOURCES = \
der.c \
der_get.c \ der_get.c \
der_put.c \ der_put.c \
der_free.c \ der_free.c \
der_length.c \ der_length.c \
der_copy.c \ der_copy.c \
der_cmp.c \ der_cmp.c \
extra.c \
timegm.c \ timegm.c \
$(BUILT_SOURCES) $(BUILT_SOURCES)
@@ -128,22 +361,78 @@ check_der_LDADD = \
check_gen_LDADD = $(check_der_LDADD) check_gen_LDADD = $(check_der_LDADD)
asn1_print_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) \ $(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 $(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 rfc2459_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/rfc2459.asn1
./asn1_compile$(EXEEXT) $(srcdir)/k5.asn1 krb5_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 $(libasn1_la_OBJECTS): krb5_asn1.h asn1_err.h
$(check_gen_OBJECTS): test_asn1.h
$(asn1_print_OBJECTS): krb5_asn1.h $(asn1_print_OBJECTS): krb5_asn1.h
parse.h: parse.c
EXTRA_DIST = asn1_err.et EXTRA_DIST = asn1_err.et

View File

@@ -6,6 +6,12 @@
#ifndef __asn1_common_definitions__ #ifndef __asn1_common_definitions__
#define __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 { typedef struct heim_octet_string {
size_t length; size_t length;
void *data; void *data;
@@ -13,10 +19,44 @@ typedef struct heim_octet_string {
typedef char *heim_general_string; typedef char *heim_general_string;
typedef char *heim_utf8_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 { typedef struct heim_oid {
size_t length; size_t length;
unsigned *components; unsigned *components;
} heim_oid; } 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 #endif

187
lib/asn1/asn1_gen.c Normal file
View 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]);
}

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -37,55 +37,20 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <getarg.h> #include <getarg.h>
#include <err.h> #include <err.h>
#include <der.h>
RCSID("$Id$"); RCSID("$Id$");
const char *class_names[] = { static int indent_flag = 1;
"UNIV", /* 0 */
"APPL", /* 1 */
"CONTEXT", /* 2 */
"PRIVATE" /* 3 */
};
const char *type_names[] = { static unsigned long indefinite_form_loop;
"PRIM", /* 0 */ static unsigned long indefinite_form_loop_max = 10000;
"CONS" /* 1 */
};
const char *tag_names[] = { static size_t
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
loop (unsigned char *buf, size_t len, int indent) loop (unsigned char *buf, size_t len, int indent)
{ {
unsigned char *start_buf = buf;
while (len > 0) { while (len > 0) {
int ret; int ret;
Der_class class; Der_class class;
@@ -93,7 +58,9 @@ loop (unsigned char *buf, size_t len, int indent)
int tag; int tag;
size_t sz; size_t sz;
size_t length; 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); ret = der_get_tag (buf, len, &class, &type, &tag, &sz);
if (ret) if (ret)
@@ -103,62 +70,99 @@ loop (unsigned char *buf, size_t len, int indent)
(unsigned)sz, (unsigned)len); (unsigned)sz, (unsigned)len);
buf += sz; buf += sz;
len -= sz; len -= sz;
for (i = 0; i < indent; ++i) if (indent_flag) {
printf (" "); int i;
printf ("%s %s ", class_names[class], type_names[type]); for (i = 0; i < indent; ++i)
if (tag_names[tag]) printf (" ");
printf ("%s = ", tag_names[tag]); }
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 else
printf ("tag %d = ", tag); printf ("tag %d = ", tag);
ret = der_get_length (buf, len, &length, &sz); ret = der_get_length (buf, len, &length, &sz);
if (ret) if (ret)
errx (1, "der_get_tag: %s", error_message (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; buf += sz;
len -= sz; len -= sz;
if (length == ASN1_INDEFINITE) {
if (class == ASN1_C_CONTEXT) { if ((class == ASN1_C_UNIV && type == PRIM && tag == UT_OctetString) ||
printf ("[%d]\n", tag); (class == ASN1_C_CONTEXT && type == CONS) ||
loop (buf, length, indent); (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) { } else if (class == ASN1_C_UNIV) {
switch (tag) { switch (tag) {
case UT_EndOfContent:
printf (" INDEFINITE length was %lu\n",
(unsigned long)(buf - start_buf));
break;
case UT_Set :
case UT_Sequence : case UT_Sequence :
printf ("{\n"); printf ("%lu bytes {\n", (unsigned long)length);
loop (buf, length, indent + 2); loop_length = loop (buf, length, indent + 2);
for (i = 0; i < indent; ++i) if (indent_flag) {
printf (" "); int i;
printf ("}\n"); for (i = 0; i < indent; ++i)
printf (" ");
printf ("}\n");
} else
printf ("} indent = %d\n", indent / 2);
break; break;
case UT_Integer : { case UT_Integer : {
int val; int val;
ret = der_get_int (buf, length, &val, NULL); if (length <= sizeof(val)) {
if (ret) ret = der_get_integer (buf, length, &val, NULL);
errx (1, "der_get_int: %s", error_message (ret)); if (ret)
printf ("integer %d\n", val); errx (1, "der_get_integer: %s", error_message (ret));
printf ("integer %d\n", val);
} else {
printf ("BIG NUM integer: length %d\n", length);
}
break; break;
} }
case UT_OctetString : { case UT_OctetString : {
heim_octet_string str; heim_octet_string str;
int i;
unsigned char *uc; unsigned char *uc;
ret = der_get_octet_string (buf, length, &str, NULL); ret = der_get_octet_string (buf, length, &str, NULL);
if (ret) if (ret)
errx (1, "der_get_octet_string: %s", error_message (ret)); errx (1, "der_get_octet_string: %s", error_message (ret));
printf ("(length %lu)%s", (unsigned long)str.length, printf ("(length %lu), ", (unsigned long)length);
str.length > 0 ? ", " : "");
uc = (unsigned char *)str.data; uc = (unsigned char *)str.data;
length = str.length; for (i = 0; i < min(16,length); ++i)
if (length > 16)
length = 16;
for (i = 0; i < length; ++i)
printf ("%02x", uc[i]); printf ("%02x", uc[i]);
printf ("\n"); printf ("\n");
free (str.data); free (str.data);
break; break;
} }
case UT_GeneralizedTime : case UT_GeneralizedTime :
case UT_IA5String:
case UT_UTF8String :
case UT_GeneralString : { case UT_GeneralString : {
heim_general_string str; heim_general_string str;
@@ -172,6 +176,7 @@ loop (unsigned char *buf, size_t len, int indent)
} }
case UT_OID: { case UT_OID: {
heim_oid o; heim_oid o;
int i;
ret = der_get_oid(buf, length, &o, NULL); ret = der_get_oid(buf, length, &o, NULL);
if (ret) if (ret)
@@ -185,9 +190,9 @@ loop (unsigned char *buf, size_t len, int indent)
break; break;
} }
case UT_Enumerated: { 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) if (ret)
errx (1, "der_get_enum: %s", error_message (ret)); errx (1, "der_get_enum: %s", error_message (ret));
@@ -199,6 +204,17 @@ loop (unsigned char *buf, size_t len, int indent)
break; 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; buf += length;
len -= length; len -= length;
} }
@@ -219,21 +235,20 @@ doit (const char *filename)
if (fstat (fd, &sb) < 0) if (fstat (fd, &sb) < 0)
err (1, "stat %s", filename); err (1, "stat %s", filename);
len = sb.st_size; len = sb.st_size;
buf = malloc (len); buf = emalloc (len);
if (buf == NULL)
err (1, "malloc %u", (unsigned)len);
if (read (fd, buf, len) != len) if (read (fd, buf, len) != len)
errx (1, "read failed"); errx (1, "read failed");
close (fd); close (fd);
ret = loop (buf, len, 0); ret = loop (buf, len, 0);
free (buf); free (buf);
return ret; return 0;
} }
static int version_flag; static int version_flag;
static int help_flag; static int help_flag;
struct getargs args[] = { struct getargs args[] = {
{ "indent", 0, arg_negative_flag, &indent_flag },
{ "version", 0, arg_flag, &version_flag }, { "version", 0, arg_flag, &version_flag },
{ "help", 0, arg_flag, &help_flag } { "help", 0, arg_flag, &help_flag }
}; };
@@ -249,11 +264,11 @@ usage(int code)
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int optidx = 0; int optind = 0;
setprogname (argv[0]); setprogname (argv[0]);
initialize_asn1_error_table (); initialize_asn1_error_table ();
if(getarg(args, num_args, argc, argv, &optidx)) if(getarg(args, num_args, argc, argv, &optind))
usage(1); usage(1);
if(help_flag) if(help_flag)
usage(0); usage(0);
@@ -261,8 +276,8 @@ main(int argc, char **argv)
print_version(NULL); print_version(NULL);
exit(0); exit(0);
} }
argv += optidx; argv += optind;
argc -= optidx; argc -= optind;
if (argc != 1) if (argc != 1)
usage (1); usage (1);
return doit (argv[0]); return doit (argv[0]);

167
lib/asn1/asn1_queue.h Normal file
View 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
View 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

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -34,6 +34,9 @@
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif #endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <err.h> #include <err.h>
@@ -43,6 +46,107 @@
RCSID("$Id$"); 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 static void
print_bytes (unsigned const char *buf, size_t len) 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]); 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 int
generic_test (const struct test_case *tests, generic_test (const struct test_case *tests,
unsigned ntests, unsigned ntests,
@@ -59,67 +188,181 @@ generic_test (const struct test_case *tests,
int (*encode)(unsigned char *, size_t, void *, size_t *), int (*encode)(unsigned char *, size_t, void *, size_t *),
int (*length)(void *), int (*length)(void *),
int (*decode)(unsigned char *, size_t, void *, size_t *), int (*decode)(unsigned char *, size_t, void *, size_t *),
int (*free_data)(void *),
int (*cmp)(void *a, void *b)) int (*cmp)(void *a, void *b))
{ {
unsigned char buf[4711]; unsigned char *buf, *buf2;
int i; int i;
int failures = 0; 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) struct sigaction sa, osa;
err (1, "malloc");
for (i = 0; i < ntests; ++i) { for (i = 0; i < ntests; ++i) {
int ret; int ret;
size_t sz, consumed_sz, length_sz; size_t sz, consumed_sz, length_sz, buf_sz;
unsigned char *beg;
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); tests[i].val, &sz);
beg = buf + sizeof(buf) - sz;
if (ret != 0) { if (ret != 0) {
printf ("encoding of %s failed\n", tests[i].name); printf ("encoding of %s failed %d\n", tests[i].name, ret);
++failures; ++failures;
continue;
} }
if (sz != tests[i].byte_len) { if (sz != tests[i].byte_len) {
printf ("encoding of %s has wrong len (%lu != %lu)\n", printf ("encoding of %s has wrong len (%lu != %lu)\n",
tests[i].name, tests[i].name,
(unsigned long)sz, (unsigned long)tests[i].byte_len); (unsigned long)sz, (unsigned long)tests[i].byte_len);
++failures; ++failures;
continue;
} }
current_state = "length";
length_sz = (*length) (tests[i].val); length_sz = (*length) (tests[i].val);
if (sz != length_sz) { if (sz != length_sz) {
printf ("length for %s is bad (%lu != %lu)\n", printf ("length for %s is bad (%lu != %lu)\n",
tests[i].name, (unsigned long)length_sz, (unsigned long)sz); tests[i].name, (unsigned long)length_sz, (unsigned long)sz);
++failures; ++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" printf ("encoding of %s has bad bytes:\n"
"correct: ", tests[i].name); "correct: ", tests[i].name);
print_bytes (tests[i].bytes, tests[i].byte_len); print_bytes (tests[i].bytes, tests[i].byte_len);
printf ("\nactual: "); printf ("\nactual: ");
print_bytes (beg, sz); print_bytes (buf, sz);
printf ("\n"); printf ("\n");
++failures; ++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) { if (ret != 0) {
printf ("decoding of %s failed\n", tests[i].name); printf ("decoding of %s failed %d\n", tests[i].name, ret);
++failures; ++failures;
continue;
} }
if (sz != consumed_sz) { if (sz != consumed_sz) {
printf ("different length decoding %s (%ld != %ld)\n", printf ("different length decoding %s (%ld != %ld)\n",
tests[i].name, tests[i].name,
(unsigned long)sz, (unsigned long)consumed_sz); (unsigned long)sz, (unsigned long)consumed_sz);
++failures; ++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); printf ("%s: comparison failed\n", tests[i].name);
++failures; ++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; return failures;
} }

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -41,6 +41,7 @@ struct test_case {
typedef int (*generic_encode)(unsigned char *, size_t, void *, size_t *); typedef int (*generic_encode)(unsigned char *, size_t, void *, size_t *);
typedef int (*generic_length)(void *); typedef int (*generic_length)(void *);
typedef int (*generic_decode)(unsigned char *, size_t, void *, size_t *); typedef int (*generic_decode)(unsigned char *, size_t, void *, size_t *);
typedef int (*generic_free)(void *);
int int
generic_test (const struct test_case *tests, 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 (*encode)(unsigned char *, size_t, void *, size_t *),
int (*length)(void *), int (*length)(void *),
int (*decode)(unsigned char *, size_t, void *, size_t *), int (*decode)(unsigned char *, size_t, void *, size_t *),
int (*free_data)(void *),
int (*cmp)(void *a, void *b)); 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 *);

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -56,17 +56,17 @@ static int
test_integer (void) test_integer (void)
{ {
struct test_case tests[] = { struct test_case tests[] = {
{NULL, 3, "\x02\x01\x00"}, {NULL, 1, "\x00"},
{NULL, 3, "\x02\x01\x7f"}, {NULL, 1, "\x7f"},
{NULL, 4, "\x02\x02\x00\x80"}, {NULL, 2, "\x00\x80"},
{NULL, 4, "\x02\x02\x01\x00"}, {NULL, 2, "\x01\x00"},
{NULL, 3, "\x02\x01\x80"}, {NULL, 1, "\x80"},
{NULL, 4, "\x02\x02\xff\x7f"}, {NULL, 2, "\xff\x7f"},
{NULL, 3, "\x02\x01\xff"}, {NULL, 1, "\xff"},
{NULL, 4, "\x02\x02\xff\x01"}, {NULL, 2, "\xff\x01"},
{NULL, 4, "\x02\x02\x00\xff"}, {NULL, 2, "\x00\xff"},
{NULL, 6, "\x02\x04\x80\x00\x00\x00"}, {NULL, 4, "\x80\x00\x00\x00"},
{NULL, 6, "\x02\x04\x7f\xff\xff\xff"} {NULL, 4, "\x7f\xff\xff\xff"}
}; };
int values[] = {0, 127, 128, 256, -128, -129, -1, -255, 255, int values[] = {0, 127, 128, 256, -128, -129, -1, -255, 255,
@@ -77,21 +77,23 @@ test_integer (void)
for (i = 0; i < ntests; ++i) { for (i = 0; i < ntests; ++i) {
tests[i].val = &values[i]; tests[i].val = &values[i];
asprintf (&tests[i].name, "integer %d", 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), return generic_test (tests, ntests, sizeof(int),
(generic_encode)encode_integer, (generic_encode)der_put_integer,
(generic_length) length_integer, (generic_length) length_integer,
(generic_decode)decode_integer, (generic_decode)der_get_integer,
(generic_free)NULL,
cmp_integer); cmp_integer);
} }
static int static int
test_one_int(int val) test_one_int(int val)
{ {
int ret, dval; int len, ret, len_len, dval;
unsigned char *buf; unsigned char *buf;
size_t len_len, len;
len = _heim_len_int(val); len = _heim_len_int(val);
@@ -101,25 +103,25 @@ test_one_int(int val)
buf[len + 1] = '\xff'; buf[len + 1] = '\xff';
memset(buf + 1, 0, len); 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) { if (ret) {
printf("integer %d encode failed %d\n", val, ret); printf("integer %d encode failed %d\n", val, ret);
return 1; return 1;
} }
if (len != len_len) { if (len != len_len) {
printf("integer %d encode fail with %d len %lu, result len %lu\n", printf("integer %d encode fail with %d len %d, result len %d\n",
val, ret, (unsigned long)len, (unsigned long)len_len); val, ret, len, len_len);
return 1; return 1;
} }
ret = der_get_int(buf + 1, len, &dval, &len_len); ret = der_get_integer(buf + 1, len, &dval, &len_len);
if (ret) { if (ret) {
printf("integer %d decode failed %d\n", val, ret); printf("integer %d decode failed %d\n", val, ret);
return 1; return 1;
} }
if (len != len_len) { if (len != len_len) {
printf("integer %d decoded diffrent len %lu != %lu", printf("integer %d decoded diffrent len %d != %d",
val, (unsigned long)len, (unsigned long)len_len); val, len, len_len);
return 1; return 1;
} }
if (val != dval) { if (val != dval) {
@@ -174,14 +176,14 @@ static int
test_unsigned (void) test_unsigned (void)
{ {
struct test_case tests[] = { struct test_case tests[] = {
{NULL, 3, "\x02\x01\x00"}, {NULL, 1, "\x00"},
{NULL, 3, "\x02\x01\x7f"}, {NULL, 1, "\x7f"},
{NULL, 4, "\x02\x02\x00\x80"}, {NULL, 2, "\x00\x80"},
{NULL, 4, "\x02\x02\x01\x00"}, {NULL, 2, "\x01\x00"},
{NULL, 4, "\x02\x02\x02\x00"}, {NULL, 2, "\x02\x00"},
{NULL, 5, "\x02\x03\x00\x80\x00"}, {NULL, 3, "\x00\x80\x00"},
{NULL, 7, "\x02\x05\x00\x80\x00\x00\x00"}, {NULL, 5, "\x00\x80\x00\x00\x00"},
{NULL, 6, "\x02\x04\x7f\xff\xff\xff"} {NULL, 4, "\x7f\xff\xff\xff"}
}; };
unsigned int values[] = {0, 127, 128, 256, 512, 32768, unsigned int values[] = {0, 127, 128, 256, 512, 32768,
@@ -192,12 +194,15 @@ test_unsigned (void)
for (i = 0; i < ntests; ++i) { for (i = 0; i < ntests; ++i) {
tests[i].val = &values[i]; tests[i].val = &values[i];
asprintf (&tests[i].name, "unsigned %u", 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), return generic_test (tests, ntests, sizeof(int),
(generic_encode)encode_unsigned, (generic_encode)der_put_unsigned,
(generic_length) length_unsigned, (generic_length)length_unsigned,
(generic_decode)decode_unsigned, (generic_decode)der_get_unsigned,
(generic_free)NULL,
cmp_unsigned); cmp_unsigned);
} }
@@ -219,20 +224,63 @@ test_octet_string (void)
heim_octet_string s1 = {8, "\x01\x23\x45\x67\x89\xab\xcd\xef"}; heim_octet_string s1 = {8, "\x01\x23\x45\x67\x89\xab\xcd\xef"};
struct test_case tests[] = { 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); int ntests = sizeof(tests) / sizeof(*tests);
tests[0].val = &s1; tests[0].val = &s1;
asprintf (&tests[0].name, "a octet string"); asprintf (&tests[0].name, "a octet string");
if (tests[0].name == NULL)
errx(1, "malloc");
return generic_test (tests, ntests, sizeof(heim_octet_string), 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_length)length_octet_string,
(generic_decode)decode_octet_string, (generic_decode)der_get_octet_string,
(generic_free)free_octet_string,
cmp_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 static int
cmp_general_string (void *a, void *b) cmp_general_string (void *a, void *b)
{ {
@@ -248,17 +296,20 @@ test_general_string (void)
unsigned char *s1 = "Test User 1"; unsigned char *s1 = "Test User 1";
struct test_case tests[] = { 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); int ntests = sizeof(tests) / sizeof(*tests);
tests[0].val = &s1; tests[0].val = &s1;
asprintf (&tests[0].name, "the string \"%s\"", 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 *), 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_length)length_general_string,
(generic_decode)decode_general_string, (generic_decode)der_get_general_string,
(generic_free)free_general_string,
cmp_general_string); cmp_general_string);
} }
@@ -275,8 +326,8 @@ static int
test_generalized_time (void) test_generalized_time (void)
{ {
struct test_case tests[] = { struct test_case tests[] = {
{NULL, 17, "\x18\x0f""19700101000000Z"}, {NULL, 15, "19700101000000Z"},
{NULL, 17, "\x18\x0f""19851106210627Z"} {NULL, 15, "19851106210627Z"}
}; };
time_t values[] = {0, 500159187}; time_t values[] = {0, 500159187};
int i; int i;
@@ -285,15 +336,211 @@ test_generalized_time (void)
for (i = 0; i < ntests; ++i) { for (i = 0; i < ntests; ++i) {
tests[i].val = &values[i]; tests[i].val = &values[i];
asprintf (&tests[i].name, "time %d", (int)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), 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_length)length_generalized_time,
(generic_decode)decode_generalized_time, (generic_decode)der_get_generalized_time,
(generic_free)NULL,
cmp_generalized_time); 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 int
main(int argc, char **argv) main(int argc, char **argv)
{ {
@@ -303,8 +550,22 @@ main(int argc, char **argv)
ret += test_integer_more(); ret += test_integer_more();
ret += test_unsigned (); ret += test_unsigned ();
ret += test_octet_string (); ret += test_octet_string ();
ret += test_bmp_string ();
ret += test_general_string (); ret += test_general_string ();
ret += test_generalized_time (); 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; return ret;
} }

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -43,16 +43,26 @@
#include <asn1_err.h> #include <asn1_err.h>
#include <der.h> #include <der.h>
#include <krb5_asn1.h> #include <krb5_asn1.h>
#include <heim_asn1.h>
#include <rfc2459_asn1.h>
#include <test_asn1.h>
#include "check-common.h" #include "check-common.h"
RCSID("$Id$"); RCSID("$Id$");
static char *lha_princ[] = { "lha" }; static char *lha_principal[] = { "lha" };
static char *lharoot_princ[] = { "lha", "root" }; static char *lharoot_princ[] = { "lha", "root" };
static char *datan_princ[] = { "host", "nutcracker.e.kth.se" }; 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) \ #define COMPARE_STRING(ac,bc,e) \
do { if (strcmp((ac)->e, (bc)->e) != 0) return 1; } while(0) do { if (strcmp((ac)->e, (bc)->e) != 0) return 1; } while(0)
#define COMPARE_INTEGER(ac,bc,e) \ #define COMPARE_INTEGER(ac,bc,e) \
@@ -101,7 +111,7 @@ test_principal (void)
Principal values[] = { 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_PRINCIPAL, { 2, lharoot_princ } }, "SU.SE" },
{ { KRB5_NT_SRV_HST, { 2, datan_princ } }, "E.KTH.SE" } { { KRB5_NT_SRV_HST, { 2, datan_princ } }, "E.KTH.SE" }
}; };
@@ -117,6 +127,7 @@ test_principal (void)
(generic_encode)encode_Principal, (generic_encode)encode_Principal,
(generic_length)length_Principal, (generic_length)length_Principal,
(generic_decode)decode_Principal, (generic_decode)decode_Principal,
(generic_free)free_Principal,
cmp_principal); cmp_principal);
} }
@@ -161,7 +172,7 @@ test_authenticator (void)
}; };
Authenticator values[] = { 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 }, NULL, 10, 99, NULL, NULL, NULL },
{ 5, "SU.SE", { KRB5_NT_PRINCIPAL, { 2, lharoot_princ } }, { 5, "SU.SE", { KRB5_NT_PRINCIPAL, { 2, lharoot_princ } },
NULL, 292, 999, NULL, NULL, NULL } NULL, 292, 999, NULL, NULL, NULL }
@@ -178,111 +189,496 @@ test_authenticator (void)
(generic_encode)encode_Authenticator, (generic_encode)encode_Authenticator,
(generic_length)length_Authenticator, (generic_length)length_Authenticator,
(generic_decode)decode_Authenticator, (generic_decode)decode_Authenticator,
(generic_free)free_Authenticator,
cmp_authenticator); cmp_authenticator);
} }
static int static int
cmp_AuthorizationData (void *a, void *b) cmp_KRB_ERROR (void *a, void *b)
{ {
AuthorizationData *aa = a; KRB_ERROR *aa = a;
AuthorizationData *ab = b; 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; return 0;
} }
static char static_buf512[512];
static int static int
test_AuthorizationData (void) test_krb_error (void)
{ {
struct test_case tests[] = { struct test_case tests[] = {
{ NULL, 14, { NULL, 127,
(unsigned char*) (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*) (unsigned char*)
"\x30\x81\x8b\x30\x81\x88\xa0\x03\x02\x01\x01\xa1\x81\x80\x04\x7e" "\x30\x21\x31\x1f\x30\x0b\x06\x03\x55\x04\x03\x13\x04\x4c\x6f\x76"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x65\x30\x10\x06\x03\x55\x04\x07\x13\x09\x53\x54\x4f\x43\x4b\x48"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x4f\x4c\x4d",
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "Name L=STOCKHOLM+CN=Love"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\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"
} }
}; };
AuthorizationData values[] = { int ntests = sizeof(tests) / sizeof(*tests);
{ 1, NULL }, Name n1, n2;
{ 1, NULL }, RelativeDistinguishedName rdn1[1];
{ 2, NULL }, RelativeDistinguishedName rdn2[1];
{ 2, NULL } 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(&lt1, 0, sizeof(lt1));
lt1.foo = 1;
tests[0].val = &lt1;
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); int ntests = sizeof(tests) / sizeof(*tests);
for (i = 0; i < ntests; ++i) { return generic_decode_fail(tests, ntests, sizeof(TESTLargeTag),
tests[i].val = &values[i]; (generic_decode)decode_TESTLargeTag);
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;
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; static int
values[2].val[0].ad_data.length = 106; check_fail_sequence(void)
values[2].val[0].ad_data.data = static_buf512; {
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; return generic_decode_fail(tests, ntests, sizeof(TESTSeq),
values[2].val[1].ad_data.length = 1; (generic_decode)decode_TESTSeq);
values[2].val[1].ad_data.data = static_buf512; }
values[3].val[0].ad_type = 1; static int
values[3].val[0].ad_data.length = 107; check_fail_choice(void)
values[3].val[0].ad_data.data = static_buf512; {
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; return generic_decode_fail(tests, ntests, sizeof(TESTChoice1),
values[3].val[1].ad_data.length = 2; (generic_decode)decode_TESTChoice1);
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);
} }
int int
@@ -292,7 +688,20 @@ main(int argc, char **argv)
ret += test_principal (); ret += test_principal ();
ret += test_authenticator(); 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; return ret;
} }

142
lib/asn1/der.c Normal file
View 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));
}

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -36,145 +36,208 @@
#ifndef __DER_H__ #ifndef __DER_H__
#define __DER_H__ #define __DER_H__
#include <time.h>
typedef enum { typedef enum {
ASN1_C_UNIV = 0, ASN1_C_UNIV = 0,
ASN1_C_APPL = 1, ASN1_C_APPL = 1,
ASN1_C_CONTEXT = 2 , ASN1_C_CONTEXT = 2,
ASN1_C_PRIVATE = 3 ASN1_C_PRIVATE = 3
} Der_class; } Der_class;
typedef enum {PRIM = 0, CONS = 1} Der_type; typedef enum {PRIM = 0, CONS = 1} Der_type;
#define MAKE_TAG(CLASS, TYPE, TAG) (((CLASS) << 6) | ((TYPE) << 5) | (TAG))
/* Universal tags */ /* Universal tags */
enum { enum {
UT_Boolean = 1, UT_EndOfContent = 0,
UT_Integer = 2, UT_Boolean = 1,
UT_BitString = 3, UT_Integer = 2,
UT_OctetString = 4, UT_BitString = 3,
UT_Null = 5, UT_OctetString = 4,
UT_OID = 6, UT_Null = 5,
UT_Enumerated = 10, UT_OID = 6,
UT_UTF8String = 12, UT_Enumerated = 10,
UT_Sequence = 16, UT_UTF8String = 12,
UT_Set = 17, UT_Sequence = 16,
UT_PrintableString = 19, UT_Set = 17,
UT_IA5String = 22, UT_PrintableString = 19,
UT_UTCTime = 23, UT_IA5String = 22,
UT_GeneralizedTime = 24, UT_UTCTime = 23,
UT_VisibleString = 26, UT_GeneralizedTime = 24,
UT_GeneralString = 27 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 #define ASN1_INDEFINITE 0xdce0deed
#ifndef HAVE_TIMEGM typedef struct asn1_der_time_t {
time_t timegm (struct tm *); time_t dt_sec;
#endif 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, int der_get_length (const unsigned char *p, size_t len,
size_t *val, size_t *size); 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, int der_get_general_string (const unsigned char *p, size_t len,
heim_general_string *str, size_t *size); 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, int der_get_octet_string (const unsigned char *p, size_t len,
heim_octet_string *data, size_t *size); 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, int der_get_oid (const unsigned char *p, size_t len,
heim_oid *data, size_t *size); 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, int der_get_tag (const unsigned char *p, size_t len,
Der_class *class, Der_type *type, 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, int der_match_tag (const unsigned char *p, size_t len,
Der_class class, Der_type type, 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, 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 *length_ret, size_t *size);
int decode_boolean (const unsigned char*, size_t, int*, size_t*); int der_put_unsigned (unsigned char *p, size_t len, const unsigned *val, size_t*);
int decode_integer (const unsigned char*, size_t, int*, size_t*); int der_put_integer (unsigned char *p, size_t len, const int *val, size_t*);
int decode_unsigned (const unsigned char*, size_t, unsigned*, size_t*); int der_put_heim_integer (unsigned char *p, size_t len,
int decode_enumerated (const unsigned char*, size_t, unsigned*, size_t*); const heim_integer *val, size_t*);
int decode_general_string (const unsigned char*, size_t, int der_put_boolean (unsigned char *p, size_t len, const int *val, 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_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_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, int der_put_general_string (unsigned char *p, size_t len,
const heim_general_string *str, size_t*); 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, int der_put_octet_string (unsigned char *p, size_t len,
const heim_octet_string *data, size_t*); 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, int der_put_oid (unsigned char *p, size_t len,
const heim_oid *data, size_t *size); 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 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, int der_put_length_and_tag (unsigned char*, size_t, size_t,
Der_class, Der_type, int, size_t*); Der_class, Der_type, unsigned 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*);
void free_integer (int *num); 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_general_string (heim_general_string *str);
void free_octet_string (heim_octet_string *k); void free_octet_string (heim_octet_string *k);
void free_oid (heim_oid *k); void free_oid (heim_oid *k);
void free_bit_string (heim_bit_string *k);
void free_generalized_time (time_t *t); void free_generalized_time (time_t *t);
void free_utctime (time_t *t);
void free_utf8string (heim_utf8_string*); 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_len (size_t len);
size_t length_boolean (const int *data);
size_t length_integer (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_unsigned (const unsigned *data);
size_t length_enumerated (const unsigned *data); size_t length_enumerated (const unsigned *data);
size_t length_general_string (const heim_general_string *data); size_t length_general_string (const heim_general_string *data);
size_t length_octet_string (const heim_octet_string *k); size_t length_octet_string (const heim_octet_string *k);
size_t length_oid (const heim_oid *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_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_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_general_string (const heim_general_string *, heim_general_string *);
int copy_octet_string (const heim_octet_string *, heim_octet_string *); int copy_octet_string (const heim_octet_string *, heim_octet_string *);
int copy_oid (const heim_oid *from, heim_oid *to); 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_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_oid_cmp(const heim_oid *, const heim_oid *);
int heim_octet_string_cmp(const heim_octet_string *,const heim_octet_string *); 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__ */ #endif /* __DER_H__ */

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -33,8 +33,6 @@
#include "der_locl.h" #include "der_locl.h"
RCSID("$Id$");
int int
heim_oid_cmp(const heim_oid *p, const heim_oid *q) 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 p->length - q->length;
return memcmp(p->data, q->data, p->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]));
}

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -44,6 +44,49 @@ copy_general_string (const heim_general_string *from, heim_general_string *to)
return 0; 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 int
copy_octet_string (const heim_octet_string *from, heim_octet_string *to) 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; 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 int
copy_oid (const heim_oid *from, heim_oid *to) 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)); to->length * sizeof(*to->components));
return 0; 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;
}

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -42,11 +42,56 @@ free_general_string (heim_general_string *str)
*str = NULL; *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 void
free_octet_string (heim_octet_string *k) free_octet_string (heim_octet_string *k)
{ {
free(k->data); free(k->data);
k->data = NULL; k->data = NULL;
k->length = 0;
}
void
free_heim_integer (heim_integer *k)
{
free(k->data);
k->data = NULL;
k->length = 0;
} }
void void
@@ -54,4 +99,13 @@ free_oid (heim_oid *k)
{ {
free(k->components); free(k->components);
k->components = NULL; k->components = NULL;
k->length = 0;
}
void
free_bit_string (heim_bit_string *k)
{
free(k->data);
k->data = NULL;
k->length = 0;
} }

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -45,13 +45,18 @@ RCSID("$Id$");
* Either 0 or an error code is returned. * Either 0 or an error code is returned.
*/ */
static int int
der_get_unsigned (const unsigned char *p, size_t len, der_get_unsigned (const unsigned char *p, size_t len,
unsigned *ret, size_t *size) unsigned *ret, size_t *size)
{ {
unsigned val = 0; unsigned val = 0;
size_t oldlen = len; size_t oldlen = len;
if (len == sizeof(unsigned) + 1 && p[0] == 0)
;
else if (len > sizeof(unsigned))
return ASN1_OVERRUN;
while (len--) while (len--)
val = val * 256 + *p++; val = val * 256 + *p++;
*ret = val; *ret = val;
@@ -60,12 +65,15 @@ der_get_unsigned (const unsigned char *p, size_t len,
} }
int int
der_get_int (const unsigned char *p, size_t len, der_get_integer (const unsigned char *p, size_t len,
int *ret, size_t *size) int *ret, size_t *size)
{ {
int val = 0; int val = 0;
size_t oldlen = len; size_t oldlen = len;
if (len > sizeof(int))
return ASN1_OVERRUN;
if (len > 0) { if (len > 0) {
val = (signed char)*p++; val = (signed char)*p++;
while (--len) while (--len)
@@ -76,19 +84,6 @@ der_get_int (const unsigned char *p, size_t len,
return 0; 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 int
der_get_length (const unsigned char *p, size_t len, der_get_length (const unsigned char *p, size_t len,
size_t *val, size_t *size) size_t *val, size_t *size)
@@ -123,12 +118,28 @@ der_get_length (const unsigned char *p, size_t len,
return 0; 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 int
der_get_general_string (const unsigned char *p, size_t len, der_get_general_string (const unsigned char *p, size_t len,
heim_general_string *str, size_t *size) heim_general_string *str, size_t *size)
{ {
char *s; char *s;
if (len > SIZE_T_MAX - 1)
return ASN1_BAD_LENGTH;
s = malloc (len + 1); s = malloc (len + 1);
if (s == NULL) if (s == NULL)
return ENOMEM; return ENOMEM;
@@ -139,6 +150,70 @@ der_get_general_string (const unsigned char *p, size_t len,
return 0; 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 int
der_get_octet_string (const unsigned char *p, size_t len, der_get_octet_string (const unsigned char *p, size_t len,
heim_octet_string *data, size_t *size) heim_octet_string *data, size_t *size)
@@ -152,6 +227,108 @@ der_get_octet_string (const unsigned char *p, size_t len,
return 0; 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 int
der_get_oid (const unsigned char *p, size_t len, der_get_oid (const unsigned char *p, size_t len,
heim_oid *data, size_t *size) heim_oid *data, size_t *size)
@@ -162,6 +339,9 @@ der_get_oid (const unsigned char *p, size_t len,
if (len < 1) if (len < 1)
return ASN1_OVERRUN; return ASN1_OVERRUN;
if (len > SIZE_T_MAX - 1)
return ASN1_BAD_LENGTH;
data->components = malloc((len + 1) * sizeof(*data->components)); data->components = malloc((len + 1) * sizeof(*data->components));
if (data->components == NULL) if (data->components == NULL)
return ENOMEM; return ENOMEM;
@@ -170,15 +350,21 @@ der_get_oid (const unsigned char *p, size_t len,
--len; --len;
++p; ++p;
for (n = 2; len > 0; ++n) { for (n = 2; len > 0; ++n) {
unsigned u = 0; unsigned u = 0, u1;
do { do {
--len; --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); } while (len > 0 && p[-1] & 0x80);
data->components[n] = u; data->components[n] = u;
} }
if (len > 0 && p[-1] & 0x80) { if (n > 2 && p[-1] & 0x80) {
free_oid (data); free_oid (data);
return ASN1_OVERRUN; return ASN1_OVERRUN;
} }
@@ -191,21 +377,39 @@ der_get_oid (const unsigned char *p, size_t len,
int int
der_get_tag (const unsigned char *p, size_t len, der_get_tag (const unsigned char *p, size_t len,
Der_class *class, Der_type *type, Der_class *class, Der_type *type,
int *tag, size_t *size) unsigned int *tag, size_t *size)
{ {
size_t ret = 0;
if (len < 1) if (len < 1)
return ASN1_OVERRUN; return ASN1_OVERRUN;
*class = (Der_class)(((*p) >> 6) & 0x03); *class = (Der_class)(((*p) >> 6) & 0x03);
*type = (Der_type)(((*p) >> 5) & 0x01); *type = (Der_type)(((*p) >> 5) & 0x01);
*tag = (*p) & 0x1F; *tag = (*p) & 0x1f;
if(size) *size = 1; 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; return 0;
} }
int int
der_match_tag (const unsigned char *p, size_t len, der_match_tag (const unsigned char *p, size_t len,
Der_class class, Der_type type, Der_class class, Der_type type,
int tag, size_t *size) unsigned int tag, size_t *size)
{ {
size_t l; size_t l;
Der_class thisclass; Der_class thisclass;
@@ -227,7 +431,7 @@ der_match_tag (const unsigned char *p, size_t len,
int int
der_match_tag_and_length (const unsigned char *p, size_t len, 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 *length_ret, size_t *size)
{ {
size_t l, ret = 0; size_t l, ret = 0;
@@ -238,7 +442,6 @@ der_match_tag_and_length (const unsigned char *p, size_t len,
p += l; p += l;
len -= l; len -= l;
ret += l; ret += l;
e = der_get_length (p, len, length_ret, &l); e = der_get_length (p, len, length_ret, &l);
if (e) return e; if (e) return e;
p += l; p += l;
@@ -248,281 +451,21 @@ der_match_tag_and_length (const unsigned char *p, size_t len,
return 0; return 0;
} }
int /*
decode_boolean (const unsigned char *p, size_t len, * Old versions of DCE was based on a very early beta of the MIT code,
int *num, size_t *size) * which used MAVROS for ASN.1 encoding. MAVROS had the interesting
{ * feature that it encoded data in the forward direction, which has
size_t ret = 0; * it's problems, since you have no idea how long the data will be
size_t l, reallen; * until after you're done. MAVROS solved this by reserving one byte
int e; * for length, and later, if the actual length was longer, it reverted
* to indefinite, BER style, lengths. The version of MAVROS used by
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_Boolean, &l); * the DCE people could apparently generate correct X.509 DER encodings, and
if (e) return e; * did this by making space for the length after encoding, but
p += l; * unfortunately this feature wasn't used with Kerberos.
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;
}
int int
decode_integer (const unsigned char *p, size_t len, _heim_fix_dce(size_t reallen, 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)
{ {
if(reallen == ASN1_INDEFINITE) if(reallen == ASN1_INDEFINITE)
return 1; return 1;
@@ -531,3 +474,25 @@ fix_dce(size_t reallen, size_t *len)
*len = reallen; *len = reallen;
return 0; 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;
}

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -39,11 +39,17 @@ size_t
_heim_len_unsigned (unsigned val) _heim_len_unsigned (unsigned val)
{ {
size_t ret = 0; size_t ret = 0;
int last_val_gt_128;
do { do {
++ret; ++ret;
last_val_gt_128 = (val >= 128);
val /= 256; val /= 256;
} while (val); } while (val);
if(last_val_gt_128)
ret++;
return ret; return ret;
} }
@@ -83,12 +89,10 @@ len_oid (const heim_oid *oid)
for (n = 2; n < oid->length; ++n) { for (n = 2; n < oid->length; ++n) {
unsigned u = oid->components[n]; unsigned u = oid->components[n];
++ret; do {
u /= 128;
while (u > 0) {
++ret; ++ret;
u /= 128; u /= 128;
} } while(u > 0);
} }
return ret; return ret;
} }
@@ -98,68 +102,91 @@ length_len (size_t len)
{ {
if (len < 128) if (len < 128)
return 1; return 1;
else else {
return _heim_len_unsigned (len) + 1; int ret = 0;
} do {
++ret;
size_t len /= 256;
length_boolean (const int *data) } while (len);
{ return ret + 1;
return 1 + length_len(1) + 1; }
} }
size_t size_t
length_integer (const int *data) length_integer (const int *data)
{ {
size_t len = _heim_len_int (*data); return _heim_len_int (*data);
return 1 + length_len(len) + len;
} }
size_t size_t
length_unsigned (const unsigned *data) length_unsigned (const unsigned *data)
{ {
unsigned val = *data; return _heim_len_unsigned(*data);
size_t len = 0;
while (val > 255) {
++len;
val /= 256;
}
len++;
if (val >= 128)
len++;
return 1 + length_len(len) + len;
} }
size_t size_t
length_enumerated (const unsigned *data) length_enumerated (const unsigned *data)
{ {
size_t len = _heim_len_int (*data); return _heim_len_int (*data);
return 1 + length_len(len) + len;
} }
size_t size_t
length_general_string (const heim_general_string *data) length_general_string (const heim_general_string *data)
{ {
char *str = *data; return strlen(*data);
size_t len = strlen(str); }
return 1 + length_len(len) + len;
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 size_t
length_octet_string (const heim_octet_string *k) 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 size_t
length_oid (const heim_oid *k) length_oid (const heim_oid *k)
{ {
size_t len = len_oid (k); return len_oid (k);
return 1 + length_len(len) + len;
} }
size_t size_t
@@ -168,8 +195,32 @@ length_generalized_time (const time_t *t)
heim_octet_string k; heim_octet_string k;
size_t ret; size_t ret;
time2generalizedtime (*t, &k); _heim_time2generalizedtime (*t, &k, 1);
ret = 1 + length_len(k.length) + k.length; ret = k.length;
free (k.data); free(k.data);
return ret; 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;
}

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -53,6 +53,10 @@
#include <asn1_err.h> #include <asn1_err.h>
#include <der.h> #include <der.h>
#ifndef HAVE_TIMEGM
time_t timegm (struct tm *);
#endif
size_t _heim_len_unsigned (unsigned); size_t _heim_len_unsigned (unsigned);
size_t _heim_len_int (int); size_t _heim_len_int (int);

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -43,10 +43,11 @@ RCSID("$Id$");
* The return value is 0 or an error. * The return value is 0 or an error.
*/ */
static int int
der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size) der_put_unsigned (unsigned char *p, size_t len, const unsigned *v, size_t *size)
{ {
unsigned char *base = p; unsigned char *base = p;
unsigned val = *v;
if (val) { if (val) {
while (len > 0 && 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) if (val != 0)
return ASN1_OVERFLOW; return ASN1_OVERFLOW;
else { else {
if(p[1] >= 128) {
if(len < 1)
return ASN1_OVERFLOW;
*p-- = 0;
}
*size = base - p; *size = base - p;
return 0; return 0;
} }
@@ -70,9 +76,10 @@ der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size)
} }
int 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; unsigned char *base = p;
int val = *v;
if(val >= 0) { if(val >= 0) {
do { do {
@@ -114,22 +121,26 @@ der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
{ {
if (len < 1) if (len < 1)
return ASN1_OVERFLOW; return ASN1_OVERFLOW;
if (val < 128) { if (val < 128) {
*p = val; *p = val;
*size = 1; *size = 1;
return 0;
} else { } else {
size_t l; size_t l = 0;
int e;
e = der_put_unsigned (p, len - 1, val, &l); while(val > 0) {
if (e) if(len < 2)
return e; return ASN1_OVERFLOW;
p -= l; *p-- = val % 256;
val /= 256;
len--;
l++;
}
*p = 0x80 | l; *p = 0x80 | l;
*size = l + 1; if(size)
return 0; *size = l + 1;
} }
return 0;
} }
int int
@@ -160,6 +171,65 @@ der_put_general_string (unsigned char *p, size_t len,
return 0; 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 int
der_put_octet_string (unsigned char *p, size_t len, der_put_octet_string (unsigned char *p, size_t len,
const heim_octet_string *data, size_t *size) const heim_octet_string *data, size_t *size)
@@ -173,6 +243,98 @@ der_put_octet_string (unsigned char *p, size_t len,
return 0; 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 int
der_put_oid (unsigned char *p, size_t len, der_put_oid (unsigned char *p, size_t len,
const heim_oid *data, size_t *size) const heim_oid *data, size_t *size)
@@ -205,18 +367,39 @@ der_put_oid (unsigned char *p, size_t len,
int int
der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type, 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) if (tag <= 30) {
return ASN1_OVERFLOW; if (len < 1)
*p = (class << 6) | (type << 5) | tag; /* XXX */ return ASN1_OVERFLOW;
*size = 1; *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; return 0;
} }
int int
der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val, 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 ret = 0;
size_t l; size_t l;
@@ -239,229 +422,55 @@ der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
} }
int int
encode_boolean (unsigned char *p, size_t len, const int *data, _heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep)
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)
{ {
struct tm *tm; struct tm *tm;
size_t len; const size_t len = gtimep ? 15 : 13;
len = 15;
s->data = malloc(len + 1); s->data = malloc(len + 1);
if (s->data == NULL) if (s->data == NULL)
return ENOMEM; return ENOMEM;
s->length = len; s->length = len;
tm = gmtime (&t); tm = gmtime (&t);
snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ", if (gtimep)
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
tm->tm_hour, tm->tm_min, tm->tm_sec); 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; return 0;
} }
int int
encode_generalized_time (unsigned char *p, size_t len, der_put_bit_string (unsigned char *p, size_t len,
const time_t *t, size_t *size) const heim_bit_string *data, size_t *size)
{ {
size_t ret = 0; size_t data_size = (data->length + 7) / 8;
size_t l; if (len < data_size + 1)
heim_octet_string k; return ASN1_OVERFLOW;
int e; p -= data_size + 1;
len -= data_size + 1;
e = time2generalizedtime (*t, &k); memcpy (p+2, data->data, data_size);
if (e) if (data->length && (data->length % 8) != 0)
return e; p[1] = 8 - (data->length % 8);
e = der_put_octet_string (p, len, &k, &l); else
free (k.data); p[1] = 0;
if (e) *size = data_size + 1;
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;
return 0; 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;
}

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -103,7 +103,7 @@ int
copy_heim_any(const heim_any *from, heim_any *to) copy_heim_any(const heim_any *from, heim_any *to)
{ {
to->data = malloc(from->length); to->data = malloc(from->length);
if (to->data == NULL) if (to->data == NULL && from->length != 0)
return ENOMEM; return ENOMEM;
memcpy(to->data, from->data, from->length); memcpy(to->data, from->data, from->length);
to->length = 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)); memset(data, 0, sizeof(*data));
data->data = malloc(len); data->data = malloc(len);
if (data->data == NULL) if (data->data == NULL && len != 0)
return ENOMEM; return ENOMEM;
data->length = len; data->length = len;
memcpy(data->data, p, 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); 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);
}

File diff suppressed because it is too large Load Diff

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -35,123 +35,212 @@
RCSID("$Id$"); RCSID("$Id$");
static int used_fail;
static void static void
copy_primitive (const char *typename, const char *from, const char *to) 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); typename, from, to);
used_fail++;
} }
static void 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) { switch (t->type) {
case TType: case TType:
#if 0 #if 0
copy_type (from, to, t->symbol->type); copy_type (from, to, t->symbol->type, preserve);
#endif #endif
fprintf (codefile, "if(copy_%s(%s, %s)) return ENOMEM;\n", fprintf (codefile, "if(copy_%s(%s, %s)) goto fail;\n",
t->symbol->gen_name, from, to); t->symbol->gen_name, from, to);
break; used_fail++;
case TInteger: break;
case TUInteger: case TInteger:
case TBoolean: if (t->range == NULL && t->members == NULL) {
case TEnumerated : copy_primitive ("heim_integer", from, to);
fprintf(codefile, "*(%s) = *(%s);\n", to, from); break;
break; }
case TOctetString: case TBoolean:
copy_primitive ("octet_string", from, to); case TEnumerated :
break; fprintf(codefile, "*(%s) = *(%s);\n", to, from);
case TOID: break;
copy_primitive ("oid", from, to); case TOctetString:
break; copy_primitive ("octet_string", from, to);
case TBitString: { break;
fprintf(codefile, "*(%s) = *(%s);\n", to, from); case TBitString:
break; if (ASN1_TAILQ_EMPTY(t->members))
} copy_primitive ("bit_string", from, to);
case TSequence: { else
Member *m; fprintf(codefile, "*(%s) = *(%s);\n", to, from);
int tag = -1; break;
case TSet:
case TSequence:
case TChoice: {
Member *m, *have_ellipsis = NULL;
if (t->members == NULL) if(t->members == NULL)
break; break;
for (m = t->members; m && tag != m->val; m = m->next) { if ((t->type == TSequence || t->type == TChoice) && preserve) {
char *fn; fprintf(codefile,
char *tn; "{ 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", if(t->type == TChoice) {
m->optional ? "" : "&", from, m->gen_name); fprintf(codefile, "(%s)->element = (%s)->element;\n", to, from);
asprintf (&tn, "%s(%s)->%s", fprintf(codefile, "switch((%s)->element) {\n", from);
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;
fprintf (codefile, "if(((%s)->val = " ASN1_TAILQ_FOREACH(m, t->members, members) {
"malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n", char *fs;
to, from, to, from); char *ts;
fprintf (codefile, "return ENOMEM;\n");
fprintf(codefile, if (m->ellipsis) {
"for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n", have_ellipsis = m;
to, to, from, to); continue;
asprintf(&f, "&(%s)->val[(%s)->len]", from, to); }
asprintf(&T, "&(%s)->val[(%s)->len]", to, to);
copy_type(f, T, t->subtype); if(t->type == TChoice)
fprintf(codefile, "}\n"); fprintf(codefile, "case %s:\n", m->label);
free(f);
free(T); asprintf (&fs, "%s(%s)->%s%s",
break; m->optional ? "" : "&", from,
} t->type == TChoice ? "u." : "", m->gen_name);
case TGeneralizedTime: if (fs == NULL)
fprintf(codefile, "*(%s) = *(%s);\n", to, from); errx(1, "malloc");
break; asprintf (&ts, "%s(%s)->%s%s",
case TGeneralString: m->optional ? "" : "&", to,
copy_primitive ("general_string", from, to); t->type == TChoice ? "u." : "", m->gen_name);
break; if (ts == NULL)
case TUTF8String: errx(1, "malloc");
copy_primitive ("utf8string", from, to); if(m->optional){
break; fprintf(codefile, "if(%s) {\n", fs);
case TNull: fprintf(codefile, "%s = malloc(sizeof(*%s));\n", ts, ts);
break; fprintf(codefile, "if(%s == NULL) goto fail;\n", ts);
case TApplication: used_fail++;
copy_type (from, to, t->subtype); }
break; copy_type (fs, ts, m->type, FALSE);
default : if(m->optional){
abort (); 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 void
generate_type_copy (const Symbol *s) generate_type_copy (const Symbol *s)
{ {
int preserve = preserve_type(s->name) ? TRUE : FALSE;
used_fail = 0;
fprintf (headerfile, fprintf (headerfile,
"int copy_%s (const %s *, %s *);\n", "int copy_%s (const %s *, %s *);\n",
s->gen_name, s->gen_name, s->gen_name); s->gen_name, s->gen_name, s->gen_name);
fprintf (codefile, "int\n" fprintf (codefile, "int\n"
"copy_%s(const %s *from, %s *to)\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); 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); if (used_fail)
fprintf (codefile, "return 0;\n}\n\n"); fprintf (codefile, "fail:\n"
"free_%s(to);\n"
"return ENOMEM;\n",
s->gen_name);
fprintf(codefile,
"}\n\n");
} }

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -36,284 +36,538 @@
RCSID("$Id$"); RCSID("$Id$");
static void 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, fprintf (codefile,
"e = decode_%s(p, len, %s, &l);\n" "e = decode_%s(p, len, %s, &l);\n"
"FORW;\n", "%s;\n",
typename, 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 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) { switch (t->type) {
case TType: case TBitString:
#if 0 *cl = ASN1_C_UNIV;
decode_type (name, t->symbol->type); *ty = PRIM;
#endif *tag = UT_BitString;
fprintf (codefile,
"e = decode_%s(p, len, %s, &l);\n"
"FORW;\n",
t->symbol->gen_name, name);
break; break;
case TInteger: case TBoolean:
if(t->members == NULL) *cl = ASN1_C_UNIV;
decode_primitive ("integer", name); *ty = PRIM;
else { *tag = UT_Boolean;
char *s; break;
asprintf(&s, "(int*)%s", name); case TChoice:
if(s == NULL) errx(1, "Cannot have recursive CHOICE");
errx (1, "out of memory"); case TEnumerated:
decode_primitive ("integer", s); *cl = ASN1_C_UNIV;
free(s); *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:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_Integer;
break;
case TNull:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_Null;
break;
case TOID:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_OID;
break;
case TOctetString:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_OctetString;
break;
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; break;
case TUInteger: }
decode_primitive ("unsigned", name); 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; break;
case TBoolean:
decode_primitive ("boolean", name, forwstr);
break;
case TEnumerated: case TEnumerated:
decode_primitive ("enumerated", name); decode_primitive ("enumerated", name, forwstr);
break; break;
case TOctetString: case TOctetString:
decode_primitive ("octet_string", name); decode_primitive ("octet_string", name, forwstr);
break;
case TOID :
decode_primitive ("oid", name);
break; break;
case TBitString: { case TBitString: {
Member *m; Member *m;
int tag = -1; int pos = 0;
int pos;
fprintf (codefile, if (ASN1_TAILQ_EMPTY(t->members)) {
"e = der_match_tag_and_length (p, len, ASN1_C_UNIV, PRIM, UT_BitString," decode_primitive ("bit_string", name, forwstr);
"&reallen, &l);\n" break;
"FORW;\n" }
"if(len < reallen)\n" fprintf(codefile,
"return ASN1_OVERRUN;\n" "if (len < 1) return ASN1_OVERRUN;\n"
"p++;\n" "p++; len--; ret++;\n");
"len--;\n" fprintf(codefile,
"reallen--;\n" "do {\n"
"ret++;\n"); "if (len < 1) break;\n");
pos = 0; ASN1_TAILQ_FOREACH(m, t->members, members) {
for (m = t->members; m && tag != m->val; m = m->next) {
while (m->val / 8 > pos / 8) { while (m->val / 8 > pos / 8) {
fprintf (codefile, fprintf (codefile,
"p++; len--; reallen--; ret++;\n"); "p++; len--; ret++;\n"
"if (len < 1) break;\n");
pos += 8; pos += 8;
} }
fprintf (codefile, fprintf (codefile,
"%s->%s = (*p >> %d) & 1;\n", "(%s)->%s = (*p >> %d) & 1;\n",
name, m->gen_name, 7 - m->val % 8); name, m->gen_name, 7 - m->val % 8);
if (tag == -1)
tag = m->val;
} }
fprintf(codefile,
"} while(0);\n");
fprintf (codefile, fprintf (codefile,
"p += reallen; len -= reallen; ret += reallen;\n"); "p += len; ret += len;\n");
break; break;
} }
case TSequence: { case TSequence: {
Member *m; Member *m;
int tag = -1;
int fd_counter = unique_get_next();
int fd_counter_inner = unique_get_next();
if (t->members == NULL) if (t->members == NULL)
break; break;
fprintf (codefile, ASN1_TAILQ_FOREACH(m, t->members, members) {
"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) {
char *s; char *s;
asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name); if (m->ellipsis)
if (0 && m->type->type == TType){ continue;
if(m->optional)
fprintf (codefile, asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&",
"%s = malloc(sizeof(*%s));\n" name, m->gen_name);
"if(%s == NULL) return ENOMEM;\n", s, s, s); if (s == NULL)
fprintf (codefile, errx(1, "malloc");
"e = decode_seq_%s(p, len, %d, %d, %s, &l);\n", decode_type (s, m->type, m->optional, forwstr);
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);
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;
free (s); 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; 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: { case TSequenceOf: {
char *n; 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, fprintf (codefile,
"{\n" "{\n"
"size_t origlen = len;\n" "size_t origlen = len;\n"
"int oldret%d = ret;\n" "size_t oldret = ret;\n"
"void *tmp;\n"
"ret = 0;\n" "ret = 0;\n"
"(%s)->len = 0;\n" "(%s)->len = 0;\n"
"(%s)->val = NULL;\n" "(%s)->val = NULL;\n"
"while(ret < origlen) {\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)->len++;\n"
"(%s)->val = realloc((%s)->val, sizeof(*((%s)->val)) * (%s)->len);\n", "(%s)->val = tmp;\n",
oldret_counter, name, name, name, name, name, name, name); name, name, name, name, name, forwstr, name, name);
asprintf (&n, "&(%s)->val[(%s)->len-1]", 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, fprintf (codefile,
"len = origlen - ret;\n" "len = origlen - ret;\n"
"}\n" "}\n"
"ret += oldret%d;\n" "ret += oldret;\n"
"}\n", "}\n");
oldret_counter);
free (n); free (n);
break; break;
} }
case TGeneralizedTime: case TGeneralizedTime:
decode_primitive ("generalized_time", name); decode_primitive ("generalized_time", name, forwstr);
break; break;
case TGeneralString: 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; break;
case TUTF8String: 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; break;
case TNull: case TNull:
fprintf (codefile, fprintf (codefile, "/* NULL */\n");
"e = decode_nulltype(p, len, &l);\n"
"FORW;\n");
break; break;
case TApplication: case TOID:
fprintf (codefile, decode_primitive ("oid", name, forwstr);
"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);
break; break;
default : default :
abort (); abort ();
} }
return 0;
} }
void void
generate_type_decode (const Symbol *s) generate_type_decode (const Symbol *s)
{ {
unique_reset(); int preserve = preserve_type(s->name) ? TRUE : FALSE;
fprintf (headerfile, fprintf (headerfile,
"int " "int "
"decode_%s(const unsigned char *, size_t, %s *, size_t *);\n", "decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
s->gen_name, s->gen_name); 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" fprintf (codefile, "int\n"
"decode_%s(const unsigned char *p," "decode_%s(const unsigned char *p,"
" size_t len, %s *data, size_t *size)\n" " size_t len, %s *data, size_t *size)\n"
@@ -322,28 +576,45 @@ generate_type_decode (const Symbol *s)
switch (s->type->type) { switch (s->type->type) {
case TInteger: case TInteger:
case TUInteger:
case TBoolean: case TBoolean:
case TOctetString: case TOctetString:
case TOID: case TOID:
case TGeneralizedTime: case TGeneralizedTime:
case TGeneralString: case TGeneralString:
case TUTF8String: case TUTF8String:
case TPrintableString:
case TIA5String:
case TBMPString:
case TUniversalString:
case TUTCTime:
case TNull: case TNull:
case TEnumerated: case TEnumerated:
case TBitString: case TBitString:
case TSequence: case TSequence:
case TSequenceOf: case TSequenceOf:
case TApplication: case TSet:
case TSetOf:
case TTag:
case TType: case TType:
case TChoice:
fprintf (codefile, fprintf (codefile,
"size_t ret = 0, reallen;\n" "size_t ret = 0, reallen;\n"
"size_t l;\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, "memset(data, 0, sizeof(*data));\n");
fprintf (codefile, "reallen = 0;\n"); /* hack to avoid `unused variable' */ 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, fprintf (codefile,
"if(size) *size = ret;\n" "if(size) *size = ret;\n"
"return 0;\n"); "return 0;\n");
@@ -358,62 +629,3 @@ generate_type_decode (const Symbol *s)
} }
fprintf (codefile, "}\n\n"); 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");
}

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -39,15 +39,76 @@ static void
encode_primitive (const char *typename, const char *name) encode_primitive (const char *typename, const char *name)
{ {
fprintf (codefile, fprintf (codefile,
"e = encode_%s(p, len, %s, &l);\n" "e = der_put_%s(p, len, %s, &l);\n"
"BACK;\n", "if (e) return e;\np -= l; len -= l; ret += l;\n\n",
typename, typename,
name); 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) encode_type (const char *name, const Type *t)
{ {
int constructed = 1;
switch (t->type) { switch (t->type) {
case TType: case TType:
#if 0 #if 0
@@ -55,45 +116,60 @@ encode_type (const char *name, const Type *t)
#endif #endif
fprintf (codefile, fprintf (codefile,
"e = encode_%s(p, len, %s, &l);\n" "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); t->symbol->gen_name, name);
break; break;
case TInteger: case TInteger:
if(t->members == NULL) if(t->members) {
encode_primitive ("integer", name);
else {
char *s; char *s;
asprintf(&s, "(const int*)%s", name); asprintf(&s, "(const int*)%s", name);
if(s == NULL) if(s == NULL)
errx(1, "out of memory"); errx(1, "out of memory");
encode_primitive ("integer", s); encode_primitive ("integer", s);
free(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; break;
case TUInteger: case TBoolean:
encode_primitive ("unsigned", name); encode_primitive ("boolean", name);
constructed = 0;
break; break;
case TOctetString: case TOctetString:
encode_primitive ("octet_string", name); encode_primitive ("octet_string", name);
break; constructed = 0;
case TOID :
encode_primitive ("oid", name);
break; break;
case TBitString: { case TBitString: {
Member *m; Member *m;
int pos; int pos;
int rest; int rest;
int tag = -1;
if (t->members == NULL) if (ASN1_TAILQ_EMPTY(t->members)) {
encode_primitive("bit_string", name);
constructed = 0;
break; break;
}
fprintf (codefile, "{\n" fprintf (codefile, "{\n"
"unsigned char c = 0;\n"); "unsigned char c = 0;\n");
if (!rfc1510_bitstring)
fprintf (codefile,
"int bit_set = 0;\n");
#if 0
pos = t->members->prev->val; pos = t->members->prev->val;
/* fix for buggy MIT (and OSF?) code */ /* fix for buggy MIT (and OSF?) code */
if (pos > 31) if (pos > 31)
abort (); abort ();
#endif
/* /*
* It seems that if we do not always set pos to 31 here, the MIT * It seems that if we do not always set pos to 31 here, the MIT
* code will do the wrong thing. * 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 * I hate ASN.1 (and DER), but I hate it even more when everybody
* has to screw it up differently. * has to screw it up differently.
*/ */
pos = 31; pos = ASN1_TAILQ_LAST(t->members, memhead)->val;
rest = 7 - (pos % 8); 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) { while (m->val / 8 < pos / 8) {
if (!rfc1510_bitstring)
fprintf (codefile,
"if (c != 0 || bit_set) {\n");
fprintf (codefile, fprintf (codefile,
"if (len < 1) return ASN1_OVERFLOW;\n"
"*p-- = c; len--; ret++;\n" "*p-- = c; len--; ret++;\n"
"c = 0;\n"); "c = 0;\n");
if (!rfc1510_bitstring)
fprintf (codefile,
"bit_set = 1;\n"
"}\n");
pos -= 8; pos -= 8;
} }
fprintf (codefile, fprintf (codefile,
"if(%s->%s) c |= 1<<%d;\n", name, m->gen_name, "if((%s)->%s) {\n"
7 - m->val % 8); "c |= 1<<%d;\n",
name, m->gen_name, 7 - m->val % 8);
if (tag == -1) if (!rfc1510_bitstring)
tag = m->val; rest = 7 - m->val % 8;
fprintf (codefile,
"}\n");
} }
if (!rfc1510_bitstring)
fprintf (codefile,
"if (c != 0 || bit_set) {\n");
fprintf (codefile, 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" "*p-- = %d;\n"
"len -= 2;\n" "len -= 1;\n"
"ret += 2;\n" "ret += 1;\n"
"}\n\n" "}\n\n",
"e = der_put_length_and_tag (p, len, ret, ASN1_C_UNIV, PRIM,"
"UT_BitString, &l);\n"
"BACK;\n",
rest); rest);
constructed = 0;
break; break;
} }
case TEnumerated : { case TEnumerated : {
encode_primitive ("enumerated", name); encode_primitive ("enumerated", name);
constructed = 0;
break; break;
} }
case TSet:
case TSequence: { case TSequence: {
Member *m; Member *m;
int tag = -1;
int oldret_counter = unique_get_next();
if (t->members == NULL) if (t->members == NULL)
break; break;
for (m = t->members->prev; m && tag != m->val; m = m->prev) { ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
char *s; char *s;
if (m->ellipsis)
continue;
asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name); 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) if (m->optional)
fprintf (codefile, fprintf (codefile,
"if(%s)\n", "if(%s) ",
s); s);
#if 1 else if(m->defval)
fprintf (codefile, "{\n" gen_compare_defval(s + 1, m->defval);
"int oldret%d = ret;\n" fprintf (codefile, "{\n");
"ret = 0;\n", fprintf (codefile, "size_t oldret = ret;\n");
oldret_counter); fprintf (codefile, "ret = 0;\n");
#endif
encode_type (s, m->type); encode_type (s, m->type);
fprintf (codefile, fprintf (codefile, "ret += oldret;\n");
"e = der_put_length_and_tag (p, len, ret, ASN1_C_CONTEXT, CONS, " fprintf (codefile, "}\n");
"%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;
free (s); 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, fprintf (codefile,
"e = der_put_length_and_tag (p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);\n" "for(i = (%s)->len - 1; i >= 0; --i) {\n"
"BACK;\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; break;
} }
case TSequenceOf: { case TSequenceOf: {
int oldret_counter = unique_get_next();
char *n; char *n;
fprintf (codefile, fprintf (codefile,
"for(i = (%s)->len - 1; i >= 0; --i) {\n" "for(i = (%s)->len - 1; i >= 0; --i) {\n"
#if 1 "size_t oldret = ret;\n"
"int oldret%d = ret;\n"
"ret = 0;\n", "ret = 0;\n",
#else name);
,
#endif
name, oldret_counter);
asprintf (&n, "&(%s)->val[i]", name); asprintf (&n, "&(%s)->val[i]", name);
if (n == NULL)
errx(1, "malloc");
encode_type (n, t->subtype); encode_type (n, t->subtype);
fprintf (codefile, fprintf (codefile,
#if 1 "ret += oldret;\n"
"ret += oldret%d;\n" "}\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
);
free (n); free (n);
break; break;
} }
case TGeneralizedTime: case TGeneralizedTime:
encode_primitive ("generalized_time", name); encode_primitive ("generalized_time", name);
constructed = 0;
break; break;
case TGeneralString: case TGeneralString:
encode_primitive ("general_string", name); 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; break;
case TUTF8String: case TUTF8String:
encode_primitive ("utf8string", name); 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; break;
case TNull: case TNull:
fprintf (codefile, fprintf (codefile, "/* NULL */\n");
"e = encode_nulltype(p, len, &l);\n" constructed = 0;
"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);
break; break;
default: default:
abort (); abort ();
} }
return constructed;
} }
void void
@@ -244,9 +474,6 @@ generate_type_encode (const Symbol *s)
"encode_%s(unsigned char *, size_t, const %s *, size_t *);\n", "encode_%s(unsigned char *, size_t, const %s *, size_t *);\n",
s->gen_name, s->gen_name); 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" fprintf (codefile, "int\n"
"encode_%s(unsigned char *p, size_t len," "encode_%s(unsigned char *p, size_t len,"
" const %s *data, size_t *size)\n" " const %s *data, size_t *size)\n"
@@ -255,20 +482,27 @@ generate_type_encode (const Symbol *s)
switch (s->type->type) { switch (s->type->type) {
case TInteger: case TInteger:
case TUInteger:
case TBoolean: case TBoolean:
case TOctetString: case TOctetString:
case TGeneralizedTime: case TGeneralizedTime:
case TGeneralString: case TGeneralString:
case TUTCTime:
case TUTF8String: case TUTF8String:
case TPrintableString:
case TIA5String:
case TBMPString:
case TUniversalString:
case TNull: case TNull:
case TBitString: case TBitString:
case TEnumerated: case TEnumerated:
case TOID: case TOID:
case TSequence: case TSequence:
case TSequenceOf: case TSequenceOf:
case TApplication: case TSet:
case TSetOf:
case TTag:
case TType: case TType:
case TChoice:
fprintf (codefile, fprintf (codefile,
"size_t ret = 0;\n" "size_t ret = 0;\n"
"size_t l;\n" "size_t l;\n"

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -42,92 +42,136 @@ free_primitive (const char *typename, const char *name)
} }
static void static void
free_type (const char *name, const Type *t) free_type (const char *name, const Type *t, int preserve)
{ {
switch (t->type) { switch (t->type) {
case TType: case TType:
#if 0 #if 0
free_type (name, t->symbol->type); free_type (name, t->symbol->type, preserve);
#endif #endif
fprintf (codefile, "free_%s(%s);\n", t->symbol->gen_name, name); fprintf (codefile, "free_%s(%s);\n", t->symbol->gen_name, name);
break; break;
case TInteger: case TInteger:
case TUInteger: case TBoolean:
case TBoolean: case TEnumerated :
case TEnumerated : case TNull:
break; case TGeneralizedTime:
case TOctetString: case TUTCTime:
free_primitive ("octet_string", name); break;
break; case TBitString:
case TOID : if (ASN1_TAILQ_EMPTY(t->members))
free_primitive ("oid", name); free_primitive("bit_string", name);
break; break;
case TBitString: { case TOctetString:
break; free_primitive ("octet_string", name);
} break;
case TSequence: { case TChoice:
Member *m; case TSet:
int tag = -1; case TSequence: {
Member *m, *have_ellipsis = NULL;
if (t->members == NULL) if (t->members == NULL)
break; break;
if ((t->type == TSequence || t->type == TChoice) && preserve)
fprintf(codefile, "free_octet_string(&data->_save);\n");
if(t->type == TChoice)
fprintf(codefile, "switch((%s)->element) {\n", name);
for (m = t->members; m && tag != m->val; m = m->next) { ASN1_TAILQ_FOREACH(m, t->members, members) {
char *s; char *s;
asprintf (&s, "%s(%s)->%s", if (m->ellipsis){
m->optional ? "" : "&", name, m->gen_name); have_ellipsis = m;
if(m->optional) continue;
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;
fprintf (codefile, "while((%s)->len){\n", name); if(t->type == TChoice)
asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name); fprintf(codefile, "case %s:\n", m->label);
free_type(n, t->subtype); asprintf (&s, "%s(%s)->%s%s",
fprintf(codefile, m->optional ? "" : "&", name,
"(%s)->len--;\n" t->type == TChoice ? "u." : "", m->gen_name);
"}\n", if (s == NULL)
name); errx(1, "malloc");
fprintf(codefile, if(m->optional)
"free((%s)->val);\n" fprintf(codefile, "if(%s) {\n", s);
"(%s)->val = NULL;\n", name, name); free_type (s, m->type, FALSE);
free(n); if(m->optional)
break; fprintf(codefile,
} "free(%s);\n"
case TGeneralizedTime: "%s = NULL;\n"
break; "}\n",s, s);
case TGeneralString: free (s);
free_primitive ("general_string", name); if(t->type == TChoice)
break; fprintf(codefile, "break;\n");
case TUTF8String: }
free_primitive ("utf8string", name);
break; if(t->type == TChoice) {
case TNull: if (have_ellipsis)
break; fprintf(codefile,
case TApplication: "case %s:\n"
free_type (name, t->subtype); "free_octet_string(&(%s)->u.%s);\n"
break; "break;",
default : have_ellipsis->label,
abort (); 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 void
generate_type_free (const Symbol *s) generate_type_free (const Symbol *s)
{ {
int preserve = preserve_type(s->name) ? TRUE : FALSE;
fprintf (headerfile, fprintf (headerfile,
"void free_%s (%s *);\n", "void free_%s (%s *);\n",
s->gen_name, s->gen_name); s->gen_name, s->gen_name);
@@ -137,7 +181,7 @@ generate_type_free (const Symbol *s)
"{\n", "{\n",
s->gen_name, s->gen_name); s->gen_name, s->gen_name);
free_type ("data", s->type); free_type ("data", s->type, preserve);
fprintf (codefile, "}\n\n"); fprintf (codefile, "}\n\n");
} }

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -36,56 +36,48 @@
RCSID("$Id$"); RCSID("$Id$");
static void static void
generate_2int (const Symbol *s) generate_2int (const Type *t, const char *gen_name)
{ {
Type *t = s->type;
Member *m; Member *m;
int tag = -1;
fprintf (headerfile, fprintf (headerfile,
"unsigned %s2int(%s);\n", "unsigned %s2int(%s);\n",
s->gen_name, s->gen_name); gen_name, gen_name);
fprintf (codefile, fprintf (codefile,
"unsigned %s2int(%s f)\n" "unsigned %s2int(%s f)\n"
"{\n" "{\n"
"unsigned r = 0;\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", fprintf (codefile, "if(f.%s) r |= (1U << %d);\n",
m->gen_name, m->val); m->gen_name, m->val);
if (tag == -1)
tag = m->val;
} }
fprintf (codefile, "return r;\n" fprintf (codefile, "return r;\n"
"}\n\n"); "}\n\n");
} }
static void static void
generate_int2 (const Symbol *s) generate_int2 (const Type *t, const char *gen_name)
{ {
Type *t = s->type;
Member *m; Member *m;
int tag = -1;
fprintf (headerfile, fprintf (headerfile,
"%s int2%s(unsigned);\n", "%s int2%s(unsigned);\n",
s->gen_name, s->gen_name); gen_name, gen_name);
fprintf (codefile, fprintf (codefile,
"%s int2%s(unsigned n)\n" "%s int2%s(unsigned n)\n"
"{\n" "{\n"
"\t%s flags;\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) { if(t->members) {
fprintf (codefile, "\tflags.%s = (n >> %d) & 1;\n", ASN1_TAILQ_FOREACH(m, t->members, members) {
m->gen_name, m->val); fprintf (codefile, "\tflags.%s = (n >> %d) & 1;\n",
m->gen_name, m->val);
if (tag == -1) }
tag = m->val;
} }
fprintf (codefile, "\treturn flags;\n" fprintf (codefile, "\treturn flags;\n"
"}\n\n"); "}\n\n");
@@ -96,28 +88,24 @@ generate_int2 (const Symbol *s)
*/ */
static void static void
generate_units (const Symbol *s) generate_units (const Type *t, const char *gen_name)
{ {
Type *t = s->type;
Member *m; Member *m;
int tag = -1;
fprintf (headerfile, fprintf (headerfile,
"const struct units * asn1_%s_units(void);", "const struct units * asn1_%s_units(void);",
s->gen_name); gen_name);
fprintf (codefile, fprintf (codefile,
"static struct units %s_units[] = {\n", "static struct units %s_units[] = {\n",
s->gen_name); gen_name);
if(t->members) if(t->members) {
for (m = t->members->prev; m && m->val != tag; m = m->prev) { ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
fprintf (codefile, fprintf (codefile,
"\t{\"%s\",\t1U << %d},\n", m->gen_name, m->val); "\t{\"%s\",\t1U << %d},\n", m->gen_name, m->val);
if (tag == -1)
tag = m->val;
} }
}
fprintf (codefile, fprintf (codefile,
"\t{NULL,\t0}\n" "\t{NULL,\t0}\n"
@@ -127,19 +115,24 @@ generate_units (const Symbol *s)
"const struct units * asn1_%s_units(void){\n" "const struct units * asn1_%s_units(void){\n"
"return %s_units;\n" "return %s_units;\n"
"}\n\n", "}\n\n",
s->gen_name, s->gen_name); gen_name, gen_name);
} }
void 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 : case TBitString :
generate_2int (s); if (!ASN1_TAILQ_EMPTY(t->members)) {
generate_int2 (s); generate_2int (t, gen_name);
generate_units (s); generate_int2 (t, gen_name);
generate_units (t, gen_name);
}
break; break;
default : default :
break; break;

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -43,7 +43,22 @@ length_primitive (const char *typename,
fprintf (codefile, "%s += length_%s(%s);\n", variable, typename, name); 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) length_type (const char *name, const Type *t, const char *variable)
{ {
switch (t->type) { switch (t->type) {
@@ -55,19 +70,28 @@ length_type (const char *name, const Type *t, const char *variable)
variable, t->symbol->gen_name, name); variable, t->symbol->gen_name, name);
break; break;
case TInteger: case TInteger:
if(t->members == NULL) if(t->members) {
length_primitive ("integer", name, variable); char *s;
else { asprintf(&s, "(const int*)%s", name);
char *s; if(s == NULL)
asprintf(&s, "(const int*)%s", name);
if(s == NULL)
errx (1, "out of memory"); errx (1, "out of memory");
length_primitive ("integer", s, variable); length_primitive ("integer", s, variable);
free(s); 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; break;
case TUInteger: case TBoolean:
length_primitive ("unsigned", name, variable); fprintf (codefile, "%s += 1;\n", variable);
break; break;
case TEnumerated : case TEnumerated :
length_primitive ("enumerated", name, variable); length_primitive ("enumerated", name, variable);
@@ -75,71 +99,112 @@ length_type (const char *name, const Type *t, const char *variable)
case TOctetString: case TOctetString:
length_primitive ("octet_string", name, variable); length_primitive ("octet_string", name, variable);
break; break;
case TOID :
length_primitive ("oid", name, variable);
break;
case TBitString: { case TBitString: {
/* if (ASN1_TAILQ_EMPTY(t->members))
* XXX - Hope this is correct length_primitive("bit_string", name, variable);
* look at TBitString case in `encode_type' else {
*/ if (!rfc1510_bitstring) {
fprintf (codefile, "%s += 7;\n", variable); 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; break;
} }
case TSequence: { case TSet:
Member *m; case TSequence:
int tag = -1; case TChoice: {
int oldret_counter = unique_get_next(); Member *m, *have_ellipsis = NULL;
if (t->members == NULL) if (t->members == NULL)
break; break;
for (m = t->members; m && tag != m->val; m = m->next) { if(t->type == TChoice)
char *s; fprintf (codefile, "switch((%s)->element) {\n", name);
asprintf (&s, "%s(%s)->%s", ASN1_TAILQ_FOREACH(m, t->members, members) {
m->optional ? "" : "&", name, m->gen_name); 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) if (m->optional)
fprintf (codefile, "if(%s)", s); fprintf (codefile, "if(%s)", s);
else if(m->defval)
gen_compare_defval(s + 1, m->defval);
fprintf (codefile, "{\n" fprintf (codefile, "{\n"
"int oldret%d = %s;\n" "size_t oldret = %s;\n"
"%s = 0;\n", oldret_counter, variable, variable); "%s = 0;\n", variable, variable);
length_type (s, m->type, "ret"); length_type (s, m->type, "ret");
fprintf (codefile, "%s += 1 + length_len(%s) + oldret%d;\n", fprintf (codefile, "ret += oldret;\n");
variable, variable, oldret_counter);
fprintf (codefile, "}\n"); fprintf (codefile, "}\n");
if (tag == -1)
tag = m->val;
free (s); 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; break;
} }
case TSetOf:
case TSequenceOf: { case TSequenceOf: {
char *n; char *n;
int oldret_counter = unique_get_next();
int oldret_counter_inner = unique_get_next();
fprintf (codefile, fprintf (codefile,
"{\n" "{\n"
"int oldret%d = %s;\n" "int oldret = %s;\n"
"int i;\n" "int i;\n"
"%s = 0;\n", "%s = 0;\n",
oldret_counter, variable, variable); variable, variable);
fprintf (codefile, "for(i = (%s)->len - 1; i >= 0; --i){\n", name); fprintf (codefile, "for(i = (%s)->len - 1; i >= 0; --i){\n", name);
fprintf (codefile, "int oldret%d = %s;\n" fprintf (codefile, "int oldret = %s;\n"
"%s = 0;\n", oldret_counter_inner, variable, variable); "%s = 0;\n", variable, variable);
asprintf (&n, "&(%s)->val[i]", name); asprintf (&n, "&(%s)->val[i]", name);
if (n == NULL)
errx(1, "malloc");
length_type(n, t->subtype, variable); length_type(n, t->subtype, variable);
fprintf (codefile, "%s += oldret%d;\n", fprintf (codefile, "%s += oldret;\n",
variable, oldret_counter_inner); variable);
fprintf (codefile, "}\n"); fprintf (codefile, "}\n");
fprintf (codefile, fprintf (codefile,
"%s += 1 + length_len(%s) + oldret%d;\n" "%s += oldret;\n"
"}\n", variable, variable, oldret_counter); "}\n", variable);
free(n); free(n);
break; break;
} }
@@ -149,28 +214,43 @@ length_type (const char *name, const Type *t, const char *variable)
case TGeneralString: case TGeneralString:
length_primitive ("general_string", name, variable); length_primitive ("general_string", name, variable);
break; break;
case TUTCTime:
length_primitive ("utctime", name, variable);
break;
case TUTF8String: case TUTF8String:
length_primitive ("utf8string", name, variable); length_primitive ("utf8string", name, variable);
break; 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: case TNull:
fprintf (codefile, "%s += length_nulltype();\n", variable); fprintf (codefile, "/* NULL */\n");
break; break;
case TApplication: case TTag:
length_type (name, t->subtype, variable); 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; break;
case TBoolean: case TOID:
length_primitive ("boolean", name, variable); length_primitive ("oid", name, variable);
break; break;
default : default :
abort (); abort ();
} }
return 0;
} }
void void
generate_type_length (const Symbol *s) generate_type_length (const Symbol *s)
{ {
unique_reset();
fprintf (headerfile, fprintf (headerfile,
"size_t length_%s(const %s *);\n", "size_t length_%s(const %s *);\n",
s->gen_name, s->gen_name); s->gen_name, s->gen_name);

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -51,6 +51,8 @@
#include <roken.h> #include <roken.h>
#include "hash.h" #include "hash.h"
#include "symbol.h" #include "symbol.h"
#include "asn1-common.h"
#include "der.h"
void generate_type (const Symbol *); void generate_type (const Symbol *);
void generate_constant (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_length (const Symbol *s);
void generate_type_copy (const Symbol *s); void generate_type_copy (const Symbol *s);
void generate_type_maybe (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); void init_generate (const char *filename, const char *basename);
const char *get_filename (void); const char *get_filename (void);
@@ -72,6 +78,12 @@ void close_generate(void);
void add_import(const char *module); void add_import(const char *module);
int yyparse(void); int yyparse(void);
int preserve_type(const char *);
extern FILE *headerfile, *codefile, *logfile; extern FILE *headerfile, *codefile, *logfile;
extern int dce_fix;
extern int rfc1510_bitstring;
extern int error_flag;
#endif /* __GEN_LOCL_H__ */ #endif /* __GEN_LOCL_H__ */

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -34,12 +34,8 @@
#ifndef __HEIM_ANY_H__ #ifndef __HEIM_ANY_H__
#define __HEIM_ANY_H__ 1 #define __HEIM_ANY_H__ 1
typedef struct heim_any { typedef struct heim_octet_string heim_any;
size_t length; typedef struct heim_octet_string heim_any_set;
void *data;
} heim_any;
typedef struct heim_any heim_any_set;
int encode_heim_any(unsigned char *, size_t, const heim_any *, size_t *); 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 *); 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 *); void free_heim_any_set(heim_any_set *);
size_t length_heim_any_set(const 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 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__ */ #endif /* __HEIM_ANY_H__ */

View File

@@ -11,7 +11,11 @@ NAME-TYPE ::= INTEGER {
KRB5_NT_SRV_XHST(4), -- Service with host as remaining components KRB5_NT_SRV_XHST(4), -- Service with host as remaining components
KRB5_NT_UID(5), -- Unique ID KRB5_NT_UID(5), -- Unique ID
KRB5_NT_X500_PRINCIPAL(6), -- PKINIT 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 -- message types
@@ -49,6 +53,7 @@ PADATA-TYPE ::= INTEGER {
KRB5-PADATA-SAM-RESPONSE(13), -- (sam/otp) KRB5-PADATA-SAM-RESPONSE(13), -- (sam/otp)
KRB5-PADATA-PK-AS-REQ-19(14), -- (PKINIT-19) KRB5-PADATA-PK-AS-REQ-19(14), -- (PKINIT-19)
KRB5-PADATA-PK-AS-REP-19(15), -- (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-REQ(16), -- (PKINIT-25)
KRB5-PADATA-PK-AS-REP(17), -- (PKINIT-25) KRB5-PADATA-PK-AS-REP(17), -- (PKINIT-25)
KRB5-PADATA-ETYPE-INFO2(19), KRB5-PADATA-ETYPE-INFO2(19),
@@ -58,7 +63,6 @@ PADATA-TYPE ::= INTEGER {
KRB5-PADATA-SAM-ETYPE-INFO(23), KRB5-PADATA-SAM-ETYPE-INFO(23),
KRB5-PADATA-SERVER-REFERRAL(25), KRB5-PADATA-SERVER-REFERRAL(25),
KRB5-PADATA-TD-KRB-PRINCIPAL(102), -- PrincipalName 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-TRUSTED-CERTIFIERS(104), -- PKINIT
KRB5-PADATA-PK-TD-CERTIFICATE-INDEX(105), -- PKINIT KRB5-PADATA-PK-TD-CERTIFICATE-INDEX(105), -- PKINIT
KRB5-PADATA-TD-APP-DEFINED-ERROR(106), -- application specific KRB5-PADATA-TD-APP-DEFINED-ERROR(106), -- application specific
@@ -137,9 +141,13 @@ ENCTYPE ::= INTEGER {
ETYPE_DES3_CBC_NONE_CMS(-0x100a) ETYPE_DES3_CBC_NONE_CMS(-0x100a)
} }
-- this is sugar to make something ASN1 does not have: unsigned -- 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 KerberosString ::= GeneralString
@@ -156,14 +164,14 @@ Principal ::= SEQUENCE {
} }
HostAddress ::= SEQUENCE { HostAddress ::= SEQUENCE {
addr-type[0] INTEGER, addr-type[0] krb5int32,
address[1] OCTET STRING address[1] OCTET STRING
} }
-- This is from RFC1510. -- This is from RFC1510.
-- --
-- HostAddresses ::= SEQUENCE OF SEQUENCE { -- HostAddresses ::= SEQUENCE OF SEQUENCE {
-- addr-type[0] INTEGER, -- addr-type[0] krb5int32,
-- address[1] OCTET STRING -- address[1] OCTET STRING
-- } -- }
@@ -174,7 +182,7 @@ HostAddresses ::= SEQUENCE OF HostAddress
KerberosTime ::= GeneralizedTime -- Specifying UTC time zone (Z) KerberosTime ::= GeneralizedTime -- Specifying UTC time zone (Z)
AuthorizationData ::= SEQUENCE OF SEQUENCE { AuthorizationData ::= SEQUENCE OF SEQUENCE {
ad-type[0] INTEGER, ad-type[0] krb5int32,
ad-data[1] OCTET STRING ad-data[1] OCTET STRING
} }
@@ -243,23 +251,23 @@ LastReq ::= SEQUENCE OF SEQUENCE {
EncryptedData ::= SEQUENCE { EncryptedData ::= SEQUENCE {
etype[0] ENCTYPE, -- EncryptionType etype[0] ENCTYPE, -- EncryptionType
kvno[1] INTEGER OPTIONAL, kvno[1] krb5int32 OPTIONAL,
cipher[2] OCTET STRING -- ciphertext cipher[2] OCTET STRING -- ciphertext
} }
EncryptionKey ::= SEQUENCE { EncryptionKey ::= SEQUENCE {
keytype[0] INTEGER, keytype[0] krb5int32,
keyvalue[1] OCTET STRING keyvalue[1] OCTET STRING
} }
-- encoded Transited field -- encoded Transited field
TransitedEncoding ::= SEQUENCE { TransitedEncoding ::= SEQUENCE {
tr-type[0] INTEGER, -- must be registered tr-type[0] krb5int32, -- must be registered
contents[1] OCTET STRING contents[1] OCTET STRING
} }
Ticket ::= [APPLICATION 1] SEQUENCE { Ticket ::= [APPLICATION 1] SEQUENCE {
tkt-vno[0] INTEGER, tkt-vno[0] krb5int32,
realm[1] Realm, realm[1] Realm,
sname[2] PrincipalName, sname[2] PrincipalName,
enc-part[3] EncryptedData enc-part[3] EncryptedData
@@ -285,14 +293,14 @@ Checksum ::= SEQUENCE {
} }
Authenticator ::= [APPLICATION 2] SEQUENCE { Authenticator ::= [APPLICATION 2] SEQUENCE {
authenticator-vno[0] INTEGER, authenticator-vno[0] krb5int32,
crealm[1] Realm, crealm[1] Realm,
cname[2] PrincipalName, cname[2] PrincipalName,
cksum[3] Checksum OPTIONAL, cksum[3] Checksum OPTIONAL,
cusec[4] INTEGER, cusec[4] krb5int32,
ctime[5] KerberosTime, ctime[5] KerberosTime,
subkey[6] EncryptionKey OPTIONAL, subkey[6] EncryptionKey OPTIONAL,
seq-number[7] UNSIGNED OPTIONAL, seq-number[7] krb5uint32 OPTIONAL,
authorization-data[8] AuthorizationData OPTIONAL authorization-data[8] AuthorizationData OPTIONAL
} }
@@ -305,7 +313,7 @@ PA-DATA ::= SEQUENCE {
ETYPE-INFO-ENTRY ::= SEQUENCE { ETYPE-INFO-ENTRY ::= SEQUENCE {
etype[0] ENCTYPE, etype[0] ENCTYPE,
salt[1] OCTET STRING OPTIONAL, salt[1] OCTET STRING OPTIONAL,
salttype[2] INTEGER OPTIONAL salttype[2] krb5int32 OPTIONAL
} }
ETYPE-INFO ::= SEQUENCE OF ETYPE-INFO-ENTRY ETYPE-INFO ::= SEQUENCE OF ETYPE-INFO-ENTRY
@@ -320,6 +328,13 @@ ETYPE-INFO2 ::= SEQUENCE OF ETYPE-INFO2-ENTRY
METHOD-DATA ::= SEQUENCE OF PA-DATA 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-REQ-BODY ::= SEQUENCE {
kdc-options[0] KDCOptions, kdc-options[0] KDCOptions,
cname[1] PrincipalName OPTIONAL, -- Used only in AS-REQ cname[1] PrincipalName OPTIONAL, -- Used only in AS-REQ
@@ -329,7 +344,7 @@ KDC-REQ-BODY ::= SEQUENCE {
from[4] KerberosTime OPTIONAL, from[4] KerberosTime OPTIONAL,
till[5] KerberosTime OPTIONAL, till[5] KerberosTime OPTIONAL,
rtime[6] KerberosTime OPTIONAL, rtime[6] KerberosTime OPTIONAL,
nonce[7] INTEGER, nonce[7] krb5int32,
etype[8] SEQUENCE OF ENCTYPE, -- EncryptionType, etype[8] SEQUENCE OF ENCTYPE, -- EncryptionType,
-- in preference order -- in preference order
addresses[9] HostAddresses OPTIONAL, addresses[9] HostAddresses OPTIONAL,
@@ -339,7 +354,7 @@ KDC-REQ-BODY ::= SEQUENCE {
} }
KDC-REQ ::= SEQUENCE { KDC-REQ ::= SEQUENCE {
pvno[1] INTEGER, pvno[1] krb5int32,
msg-type[2] MESSAGE-TYPE, msg-type[2] MESSAGE-TYPE,
padata[3] METHOD-DATA OPTIONAL, padata[3] METHOD-DATA OPTIONAL,
req-body[4] KDC-REQ-BODY req-body[4] KDC-REQ-BODY
@@ -353,7 +368,7 @@ TGS-REQ ::= [APPLICATION 12] KDC-REQ
PA-ENC-TS-ENC ::= SEQUENCE { PA-ENC-TS-ENC ::= SEQUENCE {
patimestamp[0] KerberosTime, -- client's time patimestamp[0] KerberosTime, -- client's time
pausec[1] INTEGER OPTIONAL pausec[1] krb5int32 OPTIONAL
} }
-- draft-brezak-win2k-krb-authz-01 -- draft-brezak-win2k-krb-authz-01
@@ -362,8 +377,11 @@ PA-PAC-REQUEST ::= SEQUENCE {
-- should be included or not -- should be included or not
} }
-- PacketCable provisioning server location, PKT-SP-SEC-I09-030728.pdf
PROV-SRV-LOCATION ::= GeneralString
KDC-REP ::= SEQUENCE { KDC-REP ::= SEQUENCE {
pvno[0] INTEGER, pvno[0] krb5int32,
msg-type[1] MESSAGE-TYPE, msg-type[1] MESSAGE-TYPE,
padata[2] METHOD-DATA OPTIONAL, padata[2] METHOD-DATA OPTIONAL,
crealm[3] Realm, crealm[3] Realm,
@@ -378,7 +396,7 @@ TGS-REP ::= [APPLICATION 13] KDC-REP
EncKDCRepPart ::= SEQUENCE { EncKDCRepPart ::= SEQUENCE {
key[0] EncryptionKey, key[0] EncryptionKey,
last-req[1] LastReq, last-req[1] LastReq,
nonce[2] INTEGER, nonce[2] krb5int32,
key-expiration[3] KerberosTime OPTIONAL, key-expiration[3] KerberosTime OPTIONAL,
flags[4] TicketFlags, flags[4] TicketFlags,
authtime[5] KerberosTime, authtime[5] KerberosTime,
@@ -394,7 +412,7 @@ EncASRepPart ::= [APPLICATION 25] EncKDCRepPart
EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
AP-REQ ::= [APPLICATION 14] SEQUENCE { AP-REQ ::= [APPLICATION 14] SEQUENCE {
pvno[0] INTEGER, pvno[0] krb5int32,
msg-type[1] MESSAGE-TYPE, msg-type[1] MESSAGE-TYPE,
ap-options[2] APOptions, ap-options[2] APOptions,
ticket[3] Ticket, ticket[3] Ticket,
@@ -402,50 +420,50 @@ AP-REQ ::= [APPLICATION 14] SEQUENCE {
} }
AP-REP ::= [APPLICATION 15] SEQUENCE { AP-REP ::= [APPLICATION 15] SEQUENCE {
pvno[0] INTEGER, pvno[0] krb5int32,
msg-type[1] MESSAGE-TYPE, msg-type[1] MESSAGE-TYPE,
enc-part[2] EncryptedData enc-part[2] EncryptedData
} }
EncAPRepPart ::= [APPLICATION 27] SEQUENCE { EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
ctime[0] KerberosTime, ctime[0] KerberosTime,
cusec[1] INTEGER, cusec[1] krb5int32,
subkey[2] EncryptionKey OPTIONAL, subkey[2] EncryptionKey OPTIONAL,
seq-number[3] UNSIGNED OPTIONAL seq-number[3] krb5uint32 OPTIONAL
} }
KRB-SAFE-BODY ::= SEQUENCE { KRB-SAFE-BODY ::= SEQUENCE {
user-data[0] OCTET STRING, user-data[0] OCTET STRING,
timestamp[1] KerberosTime OPTIONAL, timestamp[1] KerberosTime OPTIONAL,
usec[2] INTEGER OPTIONAL, usec[2] krb5int32 OPTIONAL,
seq-number[3] UNSIGNED OPTIONAL, seq-number[3] krb5uint32 OPTIONAL,
s-address[4] HostAddress OPTIONAL, s-address[4] HostAddress OPTIONAL,
r-address[5] HostAddress OPTIONAL r-address[5] HostAddress OPTIONAL
} }
KRB-SAFE ::= [APPLICATION 20] SEQUENCE { KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
pvno[0] INTEGER, pvno[0] krb5int32,
msg-type[1] MESSAGE-TYPE, msg-type[1] MESSAGE-TYPE,
safe-body[2] KRB-SAFE-BODY, safe-body[2] KRB-SAFE-BODY,
cksum[3] Checksum cksum[3] Checksum
} }
KRB-PRIV ::= [APPLICATION 21] SEQUENCE { KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
pvno[0] INTEGER, pvno[0] krb5int32,
msg-type[1] MESSAGE-TYPE, msg-type[1] MESSAGE-TYPE,
enc-part[3] EncryptedData enc-part[3] EncryptedData
} }
EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE { EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE {
user-data[0] OCTET STRING, user-data[0] OCTET STRING,
timestamp[1] KerberosTime OPTIONAL, timestamp[1] KerberosTime OPTIONAL,
usec[2] INTEGER OPTIONAL, usec[2] krb5int32 OPTIONAL,
seq-number[3] UNSIGNED OPTIONAL, seq-number[3] krb5uint32 OPTIONAL,
s-address[4] HostAddress OPTIONAL, -- sender's addr s-address[4] HostAddress OPTIONAL, -- sender's addr
r-address[5] HostAddress OPTIONAL -- recip's addr r-address[5] HostAddress OPTIONAL -- recip's addr
} }
KRB-CRED ::= [APPLICATION 22] SEQUENCE { KRB-CRED ::= [APPLICATION 22] SEQUENCE {
pvno[0] INTEGER, pvno[0] krb5int32,
msg-type[1] MESSAGE-TYPE, -- KRB_CRED msg-type[1] MESSAGE-TYPE, -- KRB_CRED
tickets[2] SEQUENCE OF Ticket, tickets[2] SEQUENCE OF Ticket,
enc-part[3] EncryptedData enc-part[3] EncryptedData
@@ -467,21 +485,21 @@ KrbCredInfo ::= SEQUENCE {
EncKrbCredPart ::= [APPLICATION 29] SEQUENCE { EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
ticket-info[0] SEQUENCE OF KrbCredInfo, ticket-info[0] SEQUENCE OF KrbCredInfo,
nonce[1] INTEGER OPTIONAL, nonce[1] krb5int32 OPTIONAL,
timestamp[2] KerberosTime OPTIONAL, timestamp[2] KerberosTime OPTIONAL,
usec[3] INTEGER OPTIONAL, usec[3] krb5int32 OPTIONAL,
s-address[4] HostAddress OPTIONAL, s-address[4] HostAddress OPTIONAL,
r-address[5] HostAddress OPTIONAL r-address[5] HostAddress OPTIONAL
} }
KRB-ERROR ::= [APPLICATION 30] SEQUENCE { KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
pvno[0] INTEGER, pvno[0] krb5int32,
msg-type[1] MESSAGE-TYPE, msg-type[1] MESSAGE-TYPE,
ctime[2] KerberosTime OPTIONAL, ctime[2] KerberosTime OPTIONAL,
cusec[3] INTEGER OPTIONAL, cusec[3] krb5int32 OPTIONAL,
stime[4] KerberosTime, stime[4] KerberosTime,
susec[5] INTEGER, susec[5] krb5int32,
error-code[6] INTEGER, error-code[6] krb5int32,
crealm[7] Realm OPTIONAL, crealm[7] Realm OPTIONAL,
cname[8] PrincipalName OPTIONAL, cname[8] PrincipalName OPTIONAL,
realm[9] Realm, -- Correct realm realm[9] Realm, -- Correct realm
@@ -496,15 +514,15 @@ ChangePasswdDataMS ::= SEQUENCE {
targrealm[2] Realm OPTIONAL targrealm[2] Realm OPTIONAL
} }
EtypeList ::= SEQUENCE OF INTEGER EtypeList ::= SEQUENCE OF krb5int32
-- the client's proposed enctype list in -- the client's proposed enctype list in
-- decreasing preference order, favorite choice first -- 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 -- transited encodings
DOMAIN-X500-COMPRESS INTEGER ::= 1 DOMAIN-X500-COMPRESS krb5int32 ::= 1
-- authorization data primitives -- authorization data primitives
@@ -544,7 +562,7 @@ SAMFlags ::= BIT STRING {
} }
PA-SAM-CHALLENGE-2-BODY ::= SEQUENCE { PA-SAM-CHALLENGE-2-BODY ::= SEQUENCE {
sam-type[0] INTEGER, sam-type[0] krb5int32,
sam-flags[1] SAMFlags, sam-flags[1] SAMFlags,
sam-type-name[2] GeneralString OPTIONAL, sam-type-name[2] GeneralString OPTIONAL,
sam-track-id[3] GeneralString OPTIONAL, sam-track-id[3] GeneralString OPTIONAL,
@@ -552,8 +570,8 @@ PA-SAM-CHALLENGE-2-BODY ::= SEQUENCE {
sam-challenge[5] GeneralString OPTIONAL, sam-challenge[5] GeneralString OPTIONAL,
sam-response-prompt[6] GeneralString OPTIONAL, sam-response-prompt[6] GeneralString OPTIONAL,
sam-pk-for-sad[7] EncryptionKey OPTIONAL, sam-pk-for-sad[7] EncryptionKey OPTIONAL,
sam-nonce[8] INTEGER, sam-nonce[8] krb5int32,
sam-etype[9] INTEGER, sam-etype[9] krb5int32,
... ...
} }
@@ -564,27 +582,31 @@ PA-SAM-CHALLENGE-2 ::= SEQUENCE {
} }
PA-SAM-RESPONSE-2 ::= SEQUENCE { PA-SAM-RESPONSE-2 ::= SEQUENCE {
sam-type[0] INTEGER, sam-type[0] krb5int32,
sam-flags[1] SAMFlags, sam-flags[1] SAMFlags,
sam-track-id[2] GeneralString OPTIONAL, sam-track-id[2] GeneralString OPTIONAL,
sam-enc-nonce-or-sad[3] EncryptedData, -- PA-ENC-SAM-RESPONSE-ENC 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 { PA-ENC-SAM-RESPONSE-ENC ::= SEQUENCE {
sam-nonce[0] INTEGER, sam-nonce[0] krb5int32,
sam-sad[1] GeneralString OPTIONAL, 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 { RC2CBCParameter ::= SEQUENCE {
rc2ParameterVersion [0] INTEGER, rc2ParameterVersion krb5int32,
iv [1] OCTET STRING -- exactly 8 octets iv OCTET STRING -- exactly 8 octets
} }
CBCParameter ::= OCTET STRING CBCParameter ::= OCTET STRING
END END
-- etags -r '/\([A-Za-z][-A-Za-z0-9]*\).*::=/\1/' k5.asn1 -- etags -r '/\([A-Za-z][-A-Za-z0-9]*\).*::=/\1/' k5.asn1

View File

@@ -37,5 +37,6 @@
void error_message (const char *, ...) void error_message (const char *, ...)
__attribute__ ((format (printf, 1, 2))); __attribute__ ((format (printf, 1, 2)));
extern int error_flag;
int yylex(void); int yylex(void);

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -52,62 +52,118 @@
static unsigned lineno = 1; static unsigned lineno = 1;
#define YY_NO_UNPUT
#undef ECHO #undef ECHO
static void handle_comment(int type); static void handle_comment(int type);
static char *handle_string(void);
%} %}
%% %%
INTEGER { return INTEGER; } ABSENT { return kw_ABSENT; }
BOOLEAN { return BOOLEAN; } ABSTRACT-SYNTAX { return kw_ABSTRACT_SYNTAX; }
IMPORTS { return IMPORTS; } ALL { return kw_ALL; }
FROM { return FROM; } APPLICATION { return kw_APPLICATION; }
SEQUENCE { return SEQUENCE; } AUTOMATIC { return kw_AUTOMATIC; }
CHOICE { return CHOICE; } BEGIN { return kw_BEGIN; }
OF { return OF; } BIT { return kw_BIT; }
OCTET { return OCTET; } BMPString { return kw_BMPString; }
STRING { return STRING; } BOOLEAN { return kw_BOOLEAN; }
GeneralizedTime { return GeneralizedTime; } BY { return kw_BY; }
GeneralString { return GeneralString; } CHARACTER { return kw_CHARACTER; }
UTF8String { return UTF8String; } CHOICE { return kw_CHOICE; }
NULL { return NULLTYPE; } CLASS { return kw_CLASS; }
BIT { return BIT; } COMPONENT { return kw_COMPONENT; }
APPLICATION { return APPLICATION; } COMPONENTS { return kw_COMPONENTS; }
OPTIONAL { return OPTIONAL; } CONSTRAINED { return kw_CONSTRAINED; }
BEGIN { return TBEGIN; } CONTAINING { return kw_CONTAINING; }
END { return END; } DEFAULT { return kw_DEFAULT; }
DEFAULT { return DEFAULT; } DEFINITIONS { return kw_DEFINITIONS; }
DEFINITIONS { return DEFINITIONS; } EMBEDDED { return kw_EMBEDDED; }
ENUMERATED { return ENUMERATED; } ENCODED { return kw_ENCODED; }
EXTERNAL { return EXTERNAL; } END { return kw_END; }
OBJECT { return OBJECT; } ENUMERATED { return kw_ENUMERATED; }
IDENTIFIER { return IDENTIFIER; } EXCEPT { return kw_EXCEPT; }
[-,;{}()|\"] { return *yytext; } 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 *yytext; } "]" { return *yytext; }
::= { return EEQUAL; } ::= { return EEQUAL; }
-- { handle_comment(0); } -- { handle_comment(0); }
\/\* { handle_comment(1); } \/\* { 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, yylval.constant = strtol((const char *)yytext,
&e, 0); &e, 0);
if(e == y) if(e == y)
error_message("malformed constant (%s)", yytext); error_message("malformed constant (%s)", yytext);
else else
return CONSTANT; return NUMBER;
} }
[A-Za-z][-A-Za-z0-9_]* { [A-Za-z][-A-Za-z0-9_]* {
yylval.name = strdup ((const char *)yytext); yylval.name = estrdup ((const char *)yytext);
return IDENT; return IDENTIFIER;
} }
[ \t] ; [ \t] ;
\n { ++lineno; } \n { ++lineno; }
\.\.\. { return DOTDOTDOT; } \.\.\. { return ELLIPSIS; }
\.\. { return DOTDOT; } \.\. { return RANGE; }
. { error_message("Ignoring char(%c)\n", *yytext); } . { error_message("Ignoring char(%c)\n", *yytext); }
%% %%
@@ -128,6 +184,7 @@ error_message (const char *format, ...)
fprintf (stderr, "%s:%d: ", get_filename(), lineno); fprintf (stderr, "%s:%d: ", get_filename(), lineno);
vfprintf (stderr, format, args); vfprintf (stderr, format, args);
va_end (args); va_end (args);
error_flag++;
} }
static void static void
@@ -165,6 +222,12 @@ handle_comment(int type)
seen_slash = 1; seen_slash = 1;
continue; continue;
} }
if(seen_star && c == '/') {
if(--level == 0)
return;
seen_star = 0;
continue;
}
if(c == '*') { if(c == '*') {
if(seen_slash) { if(seen_slash) {
level++; level++;
@@ -184,3 +247,50 @@ handle_comment(int type)
if(c == EOF) if(c == EOF)
error_message("unterminated comment, possibly started on line %d\n", start_lineno); 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);
}

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -33,6 +33,19 @@
/* $Id$ */ /* $Id$ */
#include <stdio.h> #ifndef __LIBASN1_H__
#include "symbol.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__ */

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -33,14 +33,32 @@
#include "gen_locl.h" #include "gen_locl.h"
#include <getarg.h> #include <getarg.h>
#include "lex.h"
RCSID("$Id$"); RCSID("$Id$");
extern FILE *yyin; 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 version_flag;
int help_flag; int help_flag;
struct getargs args[] = { 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 }, { "version", 0, arg_flag, &version_flag },
{ "help", 0, arg_flag, &help_flag } { "help", 0, arg_flag, &help_flag }
}; };
@@ -53,12 +71,14 @@ usage(int code)
exit(code); exit(code);
} }
int error_flag;
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int ret; int ret;
const char *file; char *file;
const char *name = NULL; char *name = NULL;
int optidx = 0; int optidx = 0;
setprogname(argv[0]); setprogname(argv[0]);
@@ -79,12 +99,21 @@ main(int argc, char **argv)
yyin = fopen (file, "r"); yyin = fopen (file, "r");
if (yyin == NULL) if (yyin == NULL)
err (1, "open %s", file); 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); init_generate (file, name);
initsym (); initsym ();
ret = yyparse (); ret = yyparse ();
if(ret != 0 || error_flag != 0)
exit(1);
close_generate (); close_generate ();
return ret; return 0;
} }

File diff suppressed because it is too large Load Diff

79
lib/asn1/pkcs12.asn1 Normal file
View 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
View 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
View 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

View File

@@ -1,189 +1,171 @@
-- $Id$ --
PKINIT DEFINITIONS ::= BEGIN PKINIT DEFINITIONS ::= BEGIN
IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, TypedData IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, Checksum FROM krb5
FROM krb5; IssuerAndSerialNumber, ContentInfo FROM cms
IMPORTS SignedData, EnvelopedData FROM CMS; SubjectPublicKeyInfo, AlgorithmIdentifier FROM rfc2459
IMPORTS CertificateSerialNumber, AttributeTypeAndValue, Name FROM X509; 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 { pa-pk-as-req INTEGER ::= 16
name-type[0] INTEGER, pa-pk-as-rep INTEGER ::= 17
name-string[1] SEQUENCE OF UTF8String
}
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 TrustedCA ::= SEQUENCE {
-- X.500 name encoded as a principal name caName [0] IMPLICIT OCTET STRING,
-- see Section 3.1 certificateSerialNumber [1] INTEGER OPTIONAL,
CertificateIndex ::= INTEGER subjectKeyIdentifier [2] OCTET STRING OPTIONAL,
-- 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,
... ...
} }
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-PK-AS-REQ ::= SEQUENCE {
-- PA TYPE 14 signedAuthPack [0] IMPLICIT OCTET STRING,
signedAuthPack[0] SignedData, trustedCertifiers [1] SEQUENCE OF TrustedCA OPTIONAL,
-- defined in CMS [11] kdcPkId [2] IMPLICIT OCTET STRING OPTIONAL,
-- 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.
} }
PKAuthenticator ::= SEQUENCE { PKAuthenticator ::= SEQUENCE {
kdcName[0] PrincipalName, cusec [0] INTEGER -- (0..999999) --,
kdcRealm[1] Realm, ctime [1] KerberosTime,
cusec[2] INTEGER, nonce [2] INTEGER (0..4294967295),
-- for replay prevention as in RFC1510 paChecksum [3] OCTET STRING,
ctime[3] KerberosTime, ...
-- for replay prevention as in RFC1510
nonce[4] INTEGER
} }
-- 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 { AuthPack ::= SEQUENCE {
pkAuthenticator[0] PKAuthenticator, pkAuthenticator [0] PKAuthenticator,
clientPublicValue[1] SubjectPublicKeyInfo OPTIONAL clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL,
-- if client is using Diffie-Hellman supportedCMSTypes [2] SEQUENCE OF AlgorithmIdentifier OPTIONAL,
-- (ephemeral-ephemeral only) 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 END

View File

@@ -1,21 +1,291 @@
-- $Id$ --
-- Definitions from rfc2459/rfc3280
RFC2459 DEFINITIONS ::= BEGIN RFC2459 DEFINITIONS ::= BEGIN
AttributeType ::= OBJECT-IDENTIFIER IMPORTS heim_any FROM heim;
AttributeValue ::= OCTET STRING --ANY DEFINED BY AttributeType Version ::= INTEGER {
rfc3280_version_1(0),
AttributeTypeAndValue ::= SEQUENCE { rfc3280_version_2(1),
type AttributeType, rfc3280_version_3(2)
value AttributeValue
} }
RelativeDistinguishedName ::= --SET id-pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
SEQUENCE OF AttributeTypeAndValue 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 RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
Name ::= CHOICE { -- RFC2459 Name ::= CHOICE {
x RDNSequence rdnSequence RDNSequence
} }
END 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

View File

@@ -168,25 +168,25 @@ Request ::= [ APPLICATION 0 ] SEQUENCE {
languages[2] SEQUENCE OF Language-Tag OPTIONAL, languages[2] SEQUENCE OF Language-Tag OPTIONAL,
targ-name[3] PrincipalName OPTIONAL, targ-name[3] PrincipalName OPTIONAL,
targ-realm[4] Realm 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-major[0] INTEGER DEFAULT 2,
pvno-minor[1] INTEGER DEFAULT 0, pvno-minor[1] INTEGER DEFAULT 0,
language[2] Language-Tag DEFAULT "i-default", 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-major[0] INTEGER DEFAULT 2,
pvno-minor[1] INTEGER DEFAULT 0, pvno-minor[1] INTEGER DEFAULT 0,
language[2] Language-Tag DEFAULT "i-default", language[2] Language-Tag DEFAULT "i-default",
error-code[3] ProtocolErrorCode, error-code[3] ProtocolErrorCode,
help-text[4] UTF8String OPTIONAL, help-text[4] UTF8String OPTIONAL,
-- op-error[5] Op-error OP-ERROR, op-error[5] Op-error OP-ERROR,
... ...
} }

View File

@@ -1,90 +1,110 @@
/* /*
* Copyright (c) 1997 - 2001 Kungliga Tekniska H<>gskolan * Copyright (c) 1997 - 2005 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* *
* 3. Neither the name of the Institute nor the names of its contributors * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include "gen_locl.h" #include "gen_locl.h"
#include "lex.h"
RCSID("$Id$"); RCSID("$Id$");
static Hashtab *htab; static Hashtab *htab;
static int static int
cmp (void *a, void *b) cmp(void *a, void *b)
{ {
Symbol *s1 = (Symbol *)a; Symbol *s1 = (Symbol *) a;
Symbol *s2 = (Symbol *)b; Symbol *s2 = (Symbol *) b;
return strcmp (s1->name, s2->name); return strcmp(s1->name, s2->name);
} }
static unsigned 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 void
initsym (void) initsym(void)
{ {
htab = hashtabnew (101, cmp, hash); htab = hashtabnew(101, cmp, hash);
} }
void void
output_name (char *s) output_name(char *s)
{ {
char *p; char *p;
for (p = s; *p; ++p) for (p = s; *p; ++p)
if (*p == '-') if (*p == '-')
*p = '_'; *p = '_';
} }
Symbol* Symbol *
addsym (char *name) addsym(char *name)
{ {
Symbol key, *s; Symbol key, *s;
key.name = name; key.name = name;
s = (Symbol *)hashtabsearch (htab, (void *)&key); s = (Symbol *) hashtabsearch(htab, (void *) &key);
if (s == NULL) { if (s == NULL) {
s = (Symbol *)malloc (sizeof (*s)); s = (Symbol *) emalloc(sizeof(*s));
s->name = name; s->name = name;
s->gen_name = strdup(name); s->gen_name = estrdup(name);
output_name (s->gen_name); output_name(s->gen_name);
s->stype = SUndefined; s->stype = SUndefined;
hashtabadd (htab, s); hashtabadd(htab, s);
} }
return 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;
} }

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -36,59 +36,104 @@
#ifndef _SYMBOL_H #ifndef _SYMBOL_H
#define _SYMBOL_H #define _SYMBOL_H
#include "asn1_queue.h"
enum typetype { enum typetype {
TApplication,
TBitString, TBitString,
TBoolean, TBoolean,
TChoice, TChoice,
TEnumerated, TEnumerated,
TGeneralString, TGeneralString,
TGeneralizedTime, TGeneralizedTime,
TIA5String,
TInteger, TInteger,
TNull, TNull,
TOID, TOID,
TOctetString, TOctetString,
TSequence, TPrintableString,
TSequence,
TSequenceOf, TSequenceOf,
TSet,
TSetOf,
TTag,
TType, TType,
TUInteger, TUTCTime,
TUTF8String TUTF8String,
TBMPString,
TUniversalString
}; };
typedef enum typetype Typetype; typedef enum typetype Typetype;
struct type; struct type;
struct value {
enum { booleanvalue,
nullvalue,
integervalue,
stringvalue,
objectidentifiervalue
} type;
union {
int booleanvalue;
int integervalue;
char *stringvalue;
struct objid *objectidentifiervalue;
} u;
};
struct member { struct member {
char *name; char *name;
char *gen_name; char *gen_name;
int val; char *label;
int optional; int val;
struct type *type; int optional;
struct member *next, *prev; int ellipsis;
char *defval; struct type *type;
ASN1_TAILQ_ENTRY(member) members;
struct value *defval;
}; };
typedef struct member Member; typedef struct member Member;
ASN1_TAILQ_HEAD(memhead, member);
struct symbol; struct symbol;
struct tagtype {
int tagclass;
int tagvalue;
enum { TE_IMPLICIT, TE_EXPLICIT } tagenv;
};
struct range {
int min;
int max;
};
struct type { struct type {
Typetype type; Typetype type;
int application; struct memhead *members;
Member *members; struct symbol *symbol;
struct type *subtype; struct type *subtype;
struct symbol *symbol; struct tagtype tag;
struct range *range;
}; };
typedef struct type Type; typedef struct type Type;
struct objid {
const char *label;
int value;
struct objid *next;
};
struct symbol { struct symbol {
char *name; char *name;
char *gen_name; char *gen_name;
enum { SUndefined, SConstant, Stype } stype; enum { SUndefined, SValue, Stype } stype;
int constant; struct value *value;
Type *type; Type *type;
}; };
typedef struct symbol Symbol; typedef struct symbol Symbol;
@@ -96,4 +141,5 @@ typedef struct symbol Symbol;
void initsym (void); void initsym (void);
Symbol *addsym (char *); Symbol *addsym (char *);
void output_name (char *); void output_name (char *);
int checkundefined(void);
#endif #endif

30
lib/asn1/test.asn1 Normal file
View 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
View 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

View File

@@ -1,23 +1,79 @@
-- $Id$ --
X509 DEFINITIONS ::= BEGIN 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 { AttributeType ::= OBJECT IDENTIFIER
type AttributeType,
value AttributeValue AttributeValue ::= heim_any
Attribute ::= SEQUENCE {
type AttributeType,
value AttributeValue
} }
RelativeDistinguishedName ::= --SET RelativeDistinguishedName ::= SET OF Attribute
SEQUENCE OF AttributeTypeAndValue
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
Name ::= CHOICE { -- RFC2459 DistinguishedName ::= RDNSequence
x RDNSequence
Name ::= CHOICE { -- only one possibility for now --
rdnSequence RDNSequence
} }
END 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