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
YFLAGS = -d
YFLAGS = -dt
lib_LTLIBRARIES = libasn1.la
libasn1_la_LDFLAGS = -version-info 7:0:1
libasn1_la_LDFLAGS = -version-info 6:1:1
libasn1_la_LIBADD = $(LIB_com_err)
libasn1_la_LIBADD = @LIB_com_err@
BUILT_SOURCES = \
$(gen_files:.x=.c) \
asn1_err.h \
BUILT_SOURCES = \
$(gen_files_rfc2459:.x=.c) \
$(gen_files_cms:.x=.c) \
$(gen_files_k5:.x=.c) \
$(gen_files_pkinit:.x=.c) \
$(gen_files_pkcs8:.x=.c) \
$(gen_files_pkcs9:.x=.c) \
$(gen_files_pkcs12:.x=.c) \
asn1_err.h \
asn1_err.c
gen_files = \
asn1_AD_AND_OR.x \
asn1_AD_IF_RELEVANT.x \
asn1_AD_KDCIssued.x \
asn1_AD_MANDATORY_FOR_KDC.x \
asn1_APOptions.x \
asn1_AP_REP.x \
asn1_AP_REQ.x \
asn1_AS_REP.x \
asn1_AS_REQ.x \
asn1_Authenticator.x \
asn1_AuthorizationData.x \
asn1_AUTHDATA_TYPE.x \
asn1_CBCParameter.x \
asn1_CKSUMTYPE.x \
asn1_ChangePasswdDataMS.x \
asn1_Checksum.x \
asn1_ENCTYPE.x \
asn1_ETYPE_INFO.x \
asn1_ETYPE_INFO2.x \
asn1_ETYPE_INFO2_ENTRY.x \
asn1_ETYPE_INFO_ENTRY.x \
asn1_EncAPRepPart.x \
asn1_EncASRepPart.x \
asn1_EncKDCRepPart.x \
asn1_EncKrbCredPart.x \
asn1_EncKrbPrivPart.x \
asn1_EncTGSRepPart.x \
asn1_EncTicketPart.x \
asn1_EncryptedData.x \
asn1_EncryptionKey.x \
asn1_EtypeList.x \
asn1_HostAddress.x \
asn1_HostAddresses.x \
asn1_KDCOptions.x \
asn1_KDC_REP.x \
asn1_KDC_REQ.x \
asn1_KDC_REQ_BODY.x \
asn1_KRB_CRED.x \
asn1_KRB_ERROR.x \
asn1_KRB_PRIV.x \
asn1_KRB_SAFE.x \
asn1_KRB_SAFE_BODY.x \
asn1_KerberosString.x \
asn1_KerberosTime.x \
asn1_KrbCredInfo.x \
asn1_LR_TYPE.x \
asn1_LastReq.x \
asn1_MESSAGE_TYPE.x \
asn1_METHOD_DATA.x \
asn1_NAME_TYPE.x \
asn1_PADATA_TYPE.x \
asn1_PA_DATA.x \
asn1_PA_ENC_SAM_RESPONSE_ENC.x \
asn1_PA_ENC_TS_ENC.x \
asn1_PA_PAC_REQUEST.x \
asn1_PA_SAM_CHALLENGE_2.x \
asn1_PA_SAM_CHALLENGE_2_BODY.x \
asn1_PA_SAM_REDIRECT.x \
asn1_PA_SAM_RESPONSE_2.x \
asn1_PA_SAM_TYPE.x \
asn1_Principal.x \
asn1_PrincipalName.x \
asn1_RC2CBCParameter.x \
asn1_Realm.x \
asn1_SAMFlags.x \
asn1_TGS_REP.x \
asn1_TGS_REQ.x \
asn1_Ticket.x \
asn1_TicketFlags.x \
asn1_TransitedEncoding.x \
asn1_UNSIGNED.x
gen_files_k5 = \
asn1_AD_AND_OR.x \
asn1_AD_IF_RELEVANT.x \
asn1_AD_KDCIssued.x \
asn1_AD_MANDATORY_FOR_KDC.x \
asn1_APOptions.x \
asn1_AP_REP.x \
asn1_AP_REQ.x \
asn1_AS_REP.x \
asn1_AS_REQ.x \
asn1_AUTHDATA_TYPE.x \
asn1_Authenticator.x \
asn1_AuthorizationData.x \
asn1_CKSUMTYPE.x \
asn1_ChangePasswdDataMS.x \
asn1_Checksum.x \
asn1_ENCTYPE.x \
asn1_ETYPE_INFO.x \
asn1_ETYPE_INFO2.x \
asn1_ETYPE_INFO2_ENTRY.x \
asn1_ETYPE_INFO_ENTRY.x \
asn1_EncAPRepPart.x \
asn1_EncASRepPart.x \
asn1_EncKDCRepPart.x \
asn1_EncKrbCredPart.x \
asn1_EncKrbPrivPart.x \
asn1_EncTGSRepPart.x \
asn1_EncTicketPart.x \
asn1_EncryptedData.x \
asn1_EncryptionKey.x \
asn1_EtypeList.x \
asn1_HostAddress.x \
asn1_HostAddresses.x \
asn1_KDCOptions.x \
asn1_KDC_REP.x \
asn1_KDC_REQ.x \
asn1_KDC_REQ_BODY.x \
asn1_KRB_CRED.x \
asn1_KRB_ERROR.x \
asn1_KRB_PRIV.x \
asn1_KRB_SAFE.x \
asn1_KRB_SAFE_BODY.x \
asn1_krb5int32.x \
asn1_krb5uint32.x \
asn1_KerberosString.x \
asn1_KerberosTime.x \
asn1_KrbCredInfo.x \
asn1_LR_TYPE.x \
asn1_LastReq.x \
asn1_MESSAGE_TYPE.x \
asn1_METHOD_DATA.x \
asn1_NAME_TYPE.x \
asn1_PADATA_TYPE.x \
asn1_PA_DATA.x \
asn1_PA_ENC_SAM_RESPONSE_ENC.x \
asn1_PA_ENC_TS_ENC.x \
asn1_PA_SAM_CHALLENGE_2.x \
asn1_PA_SAM_CHALLENGE_2_BODY.x \
asn1_PA_SAM_REDIRECT.x \
asn1_PA_SAM_RESPONSE_2.x \
asn1_PA_SAM_TYPE.x \
asn1_PA_PAC_REQUEST.x \
asn1_PROV_SRV_LOCATION.x \
asn1_Principal.x \
asn1_PrincipalName.x \
asn1_Realm.x \
asn1_SAMFlags.x \
asn1_TGS_REP.x \
asn1_TGS_REQ.x \
asn1_TYPED_DATA.x \
asn1_Ticket.x \
asn1_TicketFlags.x \
asn1_TransitedEncoding.x \
asn1_TypedData.x \
asn1_RC2CBCParameter.x \
asn1_CBCParameter.x
gen_files_cms = \
asn1_id_pkcs7.x \
asn1_id_pkcs7_data.x \
asn1_id_pkcs7_signedData.x \
asn1_id_pkcs7_signedAndEnvelopedData.x \
asn1_id_pkcs7_envelopedData.x \
asn1_id_pkcs7_digestedData.x \
asn1_id_pkcs7_encryptedData.x \
asn1_CMSCBCParameter.x \
asn1_CMSEncryptedData.x \
asn1_CMSRC2CBCParameter.x \
asn1_CMSVersion.x \
asn1_CMSIdentifier.x \
asn1_CertificateList.x \
asn1_CertificateRevocationLists.x \
asn1_CertificateSet.x \
asn1_CertificateSetReal.x \
asn1_ContentEncryptionAlgorithmIdentifier.x \
asn1_ContentInfo.x \
asn1_ContentType.x \
asn1_DigestAlgorithmIdentifier.x \
asn1_DigestAlgorithmIdentifiers.x \
asn1_EncapsulatedContentInfo.x \
asn1_EncryptedContent.x \
asn1_EncryptedContentInfo.x \
asn1_EncryptedKey.x \
asn1_EnvelopedData.x \
asn1_IssuerAndSerialNumber.x \
asn1_KeyEncryptionAlgorithmIdentifier.x \
asn1_KeyTransRecipientInfo.x \
asn1_OriginatorInfo.x \
asn1_RecipientIdentifier.x \
asn1_RecipientInfo.x \
asn1_RecipientInfos.x \
asn1_SignatureAlgorithmIdentifier.x \
asn1_SignatureValue.x \
asn1_SignedAttributes.x \
asn1_SignedData.x \
asn1_SignerIdentifier.x \
asn1_SignerInfo.x \
asn1_SignerInfos.x \
asn1_UnprotectedAttributes.x \
asn1_UnsignedAttributes.x
gen_files_rfc2459 = \
asn1_Version.x \
asn1_id_pkcs_1.x \
asn1_id_pkcs1_rsaEncryption.x \
asn1_id_pkcs1_md2WithRSAEncryption.x \
asn1_id_pkcs1_md5WithRSAEncryption.x \
asn1_id_pkcs1_sha1WithRSAEncryption.x \
asn1_id_pkcs_2.x \
asn1_id_pkcs2_md2.x \
asn1_id_pkcs2_md4.x \
asn1_id_pkcs2_md5.x \
asn1_id_pkcs_3.x \
asn1_id_pkcs3_rc2_cbc.x \
asn1_id_pkcs3_rc4.x \
asn1_id_pkcs3_des_ede3_cbc.x \
asn1_id_rsadsi_encalg.x \
asn1_id_rsadsi_des_ede3_cbc.x \
asn1_id_secsig_sha_1.x \
asn1_id_nit_aes_algs.x \
asn1_id_aes_128_cbc.x \
asn1_id_aes_192_cbc.x \
asn1_id_aes_256_cbc.x \
asn1_id_dhpublicnumber.x \
asn1_id_x509_ce.x \
asn1_AlgorithmIdentifier.x \
asn1_AttributeType.x \
asn1_AttributeValue.x \
asn1_TeletexStringx.x \
asn1_DirectoryString.x \
asn1_Attribute.x \
asn1_AttributeTypeAndValue.x \
asn1_RelativeDistinguishedName.x \
asn1_RDNSequence.x \
asn1_Name.x \
asn1_CertificateSerialNumber.x \
asn1_Time.x \
asn1_Validity.x \
asn1_UniqueIdentifier.x \
asn1_SubjectPublicKeyInfo.x \
asn1_Extension.x \
asn1_Extensions.x \
asn1_TBSCertificate.x \
asn1_Certificate.x \
asn1_Certificates.x \
asn1_ValidationParms.x \
asn1_DomainParameters.x \
asn1_OtherName.x \
asn1_GeneralName.x \
asn1_GeneralNames.x \
asn1_id_x509_ce_keyUsage.x \
asn1_KeyUsage.x \
asn1_id_x509_ce_authorityKeyIdentifier.x \
asn1_KeyIdentifier.x \
asn1_AuthorityKeyIdentifier.x \
asn1_id_x509_ce_subjectKeyIdentifier.x \
asn1_SubjectKeyIdentifier.x \
asn1_id_x509_ce_basicConstraints.x \
asn1_BasicConstraints.x \
asn1_id_x509_ce_nameConstraints.x \
asn1_BaseDistance.x \
asn1_GeneralSubtree.x \
asn1_GeneralSubtrees.x \
asn1_NameConstraints.x \
asn1_id_x509_ce_privateKeyUsagePeriod.x \
asn1_id_x509_ce_certificatePolicies.x \
asn1_id_x509_ce_policyMappings.x \
asn1_id_x509_ce_subjectAltName.x \
asn1_id_x509_ce_issuerAltName.x \
asn1_id_x509_ce_subjectDirectoryAttributes.x \
asn1_id_x509_ce_policyConstraints.x \
asn1_id_x509_ce_extKeyUsage.x \
asn1_id_x509_ce_cRLDistributionPoints.x \
asn1_id_x509_ce_cRLNumber.x \
asn1_id_x509_ce_deltaCRLIndicator.x \
asn1_id_x509_ce_issuingDistributionPoint.x \
asn1_id_x509_ce_cRLReasons.x \
asn1_id_x509_ce_holdInstructionCode.x \
asn1_id_x509_ce_invalidityDate.x \
asn1_id_x509_ce_certificateIssuer.x \
asn1_id_x509_ce_inhibitAnyPolicy.x \
asn1_id_x509_ce_freshestCRL.x \
asn1_DSASigValue.x \
asn1_DSAPublicKey.x \
asn1_DSAParams.x \
asn1_RSAPublicKey.x \
asn1_DigestInfo.x
gen_files_pkinit = \
asn1_id_pkinit.x \
asn1_id_pkauthdata.x \
asn1_id_pkdhkeydata.x \
asn1_id_pkrkeydata.x \
asn1_id_pkekuoid.x \
asn1_id_pkkdcekuoid.x \
asn1_DHNonce.x \
asn1_TrustedCA.x \
asn1_PA_PK_AS_REQ.x \
asn1_PKAuthenticator.x \
asn1_AuthPack.x \
asn1_TD_TRUSTED_CERTIFIERS.x \
asn1_TD_INVALID_CERTIFICATES.x \
asn1_KRB5PrincipalName.x \
asn1_AD_INITIAL_VERIFIED_CAS.x \
asn1_DHRepInfo.x \
asn1_PA_PK_AS_REP.x \
asn1_KDCDHKeyInfo.x \
asn1_ReplyKeyPack.x \
asn1_TD_DH_PARAMETERS.x \
asn1_PKAuthenticator_Win2k.x \
asn1_AuthPack_Win2k.x \
asn1_PA_PK_AS_REP_Win2k.x \
asn1_KDCDHKeyInfo_Win2k.x \
asn1_TrustedCA_19.x \
asn1_PA_PK_AS_REQ_19.x \
asn1_PA_PK_AS_REQ_Win2k.x \
asn1_PKAuthenticator_19.x \
asn1_AuthPack_19.x \
asn1_PA_PK_AS_REP_19.x \
asn1_ReplyKeyPack_19.x
gen_files_pkcs12 = \
asn1_id_pkcs_12.x \
asn1_id_pkcs_12PbeIds.x \
asn1_id_pbeWithSHAAnd128BitRC4.x \
asn1_id_pbeWithSHAAnd40BitRC4.x \
asn1_id_pbeWithSHAAnd3_KeyTripleDES_CBC.x \
asn1_id_pbeWithSHAAnd2_KeyTripleDES_CBC.x \
asn1_id_pbeWithSHAAnd128BitRC2_CBC.x \
asn1_id_pbewithSHAAnd40BitRC2_CBC.x \
asn1_id_pkcs12_bagtypes.x \
asn1_id_pkcs12_keyBag.x \
asn1_id_pkcs12_pkcs8ShroudedKeyBag.x \
asn1_id_pkcs12_certBag.x \
asn1_id_pkcs12_crlBag.x \
asn1_id_pkcs12_secretBag.x \
asn1_id_pkcs12_safeContentsBag.x \
asn1_PKCS12_MacData.x \
asn1_PKCS12_PFX.x \
asn1_PKCS12_AuthenticatedSafe.x \
asn1_PKCS12_CertBag.x \
asn1_PKCS12_Attribute.x \
asn1_PKCS12_Attributes.x \
asn1_PKCS12_SafeBag.x \
asn1_PKCS12_SafeContents.x \
asn1_PKCS12_PBEParams.x
gen_files_pkcs8 = \
asn1_PKCS8PrivateKeyAlgorithmIdentifier.x \
asn1_PKCS8PrivateKey.x \
asn1_PKCS8PrivateKeyInfo.x \
asn1_PKCS8Attributes.x \
asn1_PKCS8EncryptedPrivateKeyInfo.x \
asn1_PKCS8EncryptedData.x
gen_files_pkcs9 = \
asn1_id_pkcs_9.x \
asn1_id_pkcs_9_at_friendlyName.x \
asn1_id_pkcs_9_at_localKeyId.x \
asn1_id_pkcs_9_at_certTypes.x \
asn1_id_pkcs_9_at_certTypes_x509.x \
asn1_PKCS9_BMPString.x \
asn1_PKCS9_friendlyName.x
gen_files_test = \
asn1_TESTChoice1.x \
asn1_TESTChoice2.x \
asn1_TESTSeq.x \
asn1_TESTLargeTag.x
noinst_PROGRAMS = asn1_compile asn1_print asn1_gen
noinst_PROGRAMS = asn1_compile asn1_print
check_PROGRAMS = check-der check-gen
TESTS = check-der check-gen
check_der_SOURCES = check-der.c check-common.c
check_gen_SOURCES = check-gen.c check-common.c
asn1_gen_SOURCES = asn1_gen.c
asn1_print_SOURCES = asn1_print.c
check_der_SOURCES = check-der.c check-common.c
check_gen_SOURCES = \
check-gen.c \
check-common.c \
$(gen_files_test:.x=.c)
asn1_compile_SOURCES = \
gen.c \
@@ -110,12 +341,14 @@ asn1_compile_SOURCES = \
symbol.c
libasn1_la_SOURCES = \
der.c \
der_get.c \
der_put.c \
der_free.c \
der_length.c \
der_copy.c \
der_cmp.c \
extra.c \
timegm.c \
$(BUILT_SOURCES)
@@ -128,22 +361,78 @@ check_der_LDADD = \
check_gen_LDADD = $(check_der_LDADD)
asn1_print_LDADD = $(check_der_LDADD)
asn1_gen_LDADD = $(check_der_LDADD)
CLEANFILES = lex.c parse.c parse.h krb5_asn1.h \
CLEANFILES = lex.c parse.c parse.h \
$(BUILT_SOURCES) \
$(gen_files) asn1_files asn1_files2
$(gen_files_rfc2459) \
$(gen_files_cms) \
$(gen_files_k5) \
$(gen_files_pkinit) \
$(gen_files_pkcs8) \
$(gen_files_pkcs9) \
$(gen_files_pkcs12) \
$(gen_files_test) \
rfc2459_asn1_files rfc2459_asn1.h \
cms_asn1_files cms_asn1.h \
krb5_asn1_files krb5_asn1.h \
pkinit_asn1_files pkinit_asn1.h \
pkcs8_asn1_files pkcs8_asn1.h \
pkcs9_asn1_files pkcs9_asn1.h \
pkcs12_asn1_files pkcs12_asn1.h \
test_asn1_files test_asn1.h
include_HEADERS = krb5_asn1.h asn1_err.h der.h
include_HEADERS = asn1_err.h der.h heim_asn1.h
include_HEADERS += krb5_asn1.h
include_HEADERS += pkinit_asn1.h
include_HEADERS += cms_asn1.h
include_HEADERS += rfc2459_asn1.h
include_HEADERS += pkcs8_asn1.h
include_HEADERS += pkcs9_asn1.h
include_HEADERS += pkcs12_asn1.h
$(asn1_compile_OBJECTS): parse.h parse.c
$(gen_files) krb5_asn1.h: asn1_files
$(gen_files_k5) krb5_asn1.h: krb5_asn1_files
$(gen_files_pkinit) pkinit_asn1.h: pkinit_asn1_files
$(gen_files_pkcs8) pkcs8_asn1.h: pkcs8_asn1_files
$(gen_files_pkcs9) pkcs9_asn1.h: pkcs9_asn1_files
$(gen_files_pkcs12) pkcs12_asn1.h: pkcs12_asn1_files
$(gen_files_rfc2459) rfc2459_asn1.h: rfc2459_asn1_files
$(gen_files_cms) cms_asn1.h: cms_asn1_files
$(gen_files_test) test_asn1.h: test_asn1_files
asn1_files: asn1_compile$(EXEEXT) $(srcdir)/k5.asn1
./asn1_compile$(EXEEXT) $(srcdir)/k5.asn1 krb5_asn1
rfc2459_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/rfc2459.asn1
./asn1_compile$(EXEEXT) --preserve-binary=TBSCertificate --preserve-binary=Name $(srcdir)/rfc2459.asn1 rfc2459_asn1 || (rm -f rfc2459_asn1_files ; exit 1)
cms_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/CMS.asn1
./asn1_compile$(EXEEXT) $(srcdir)/CMS.asn1 cms_asn1 || (rm -f cms_asn1_files ; exit 1)
krb5_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/k5.asn1
./asn1_compile$(EXEEXT) --encode-rfc1510-bit-string $(srcdir)/k5.asn1 krb5_asn1 || (rm -f krb5_asn1_files ; exit 1)
pkinit_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/pkinit.asn1
./asn1_compile$(EXEEXT) $(srcdir)/pkinit.asn1 pkinit_asn1 || (rm -f pkinit_asn1_files ; exit 1)
pkcs8_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/pkcs8.asn1
./asn1_compile$(EXEEXT) $(srcdir)/pkcs8.asn1 pkcs8_asn1 || (rm -f pkcs8_asn1_files ; exit 1)
pkcs9_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/pkcs9.asn1
./asn1_compile$(EXEEXT) $(srcdir)/pkcs9.asn1 pkcs9_asn1 || (rm -f pkcs9_asn1_files ; exit 1)
pkcs12_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/pkcs12.asn1
./asn1_compile$(EXEEXT) $(srcdir)/pkcs12.asn1 pkcs12_asn1 || (rm -f pkcs12_asn1_files ; exit 1)
test_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/test.asn1
./asn1_compile$(EXEEXT) $(srcdir)/test.asn1 test_asn1 || (rm -f test_asn1_files ; exit 1)
$(libasn1_la_OBJECTS): krb5_asn1.h asn1_err.h
$(check_gen_OBJECTS): test_asn1.h
$(asn1_print_OBJECTS): krb5_asn1.h
parse.h: parse.c
EXTRA_DIST = asn1_err.et

View File

@@ -6,6 +6,12 @@
#ifndef __asn1_common_definitions__
#define __asn1_common_definitions__
typedef struct heim_integer {
size_t length;
void *data;
int negative;
} heim_integer;
typedef struct heim_octet_string {
size_t length;
void *data;
@@ -13,10 +19,44 @@ typedef struct heim_octet_string {
typedef char *heim_general_string;
typedef char *heim_utf8_string;
typedef char *heim_printable_string;
typedef char *heim_ia5_string;
typedef struct heim_bmp_string {
size_t length;
uint16_t *data;
} heim_bmp_string;
typedef struct heim_universal_string {
size_t length;
uint32_t *data;
} heim_universal_string;
typedef struct heim_oid {
size_t length;
unsigned *components;
} heim_oid;
typedef struct heim_bit_string {
size_t length;
void *data;
} heim_bit_string;
#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \
do { \
(BL) = length_##T((S)); \
(B) = malloc((BL)); \
if((B) == NULL) { \
(R) = ENOMEM; \
} else { \
(R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \
(S), (L)); \
if((R) != 0) { \
free((B)); \
(B) = NULL; \
} \
} \
} while (0)
#endif

187
lib/asn1/asn1_gen.c Normal file
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).
* All rights reserved.
*
@@ -37,55 +37,20 @@
#include <sys/stat.h>
#include <getarg.h>
#include <err.h>
#include <der.h>
RCSID("$Id$");
const char *class_names[] = {
"UNIV", /* 0 */
"APPL", /* 1 */
"CONTEXT", /* 2 */
"PRIVATE" /* 3 */
};
static int indent_flag = 1;
const char *type_names[] = {
"PRIM", /* 0 */
"CONS" /* 1 */
};
static unsigned long indefinite_form_loop;
static unsigned long indefinite_form_loop_max = 10000;
const char *tag_names[] = {
NULL, /* 0 */
NULL, /* 1 */
"Integer", /* 2 */
"BitString", /* 3 */
"OctetString", /* 4 */
"Null", /* 5 */
"ObjectID", /* 6 */
NULL, /* 7 */
NULL, /* 8 */
NULL, /* 9 */
"Enumerated", /* 10 */
NULL, /* 11 */
NULL, /* 12 */
NULL, /* 13 */
NULL, /* 14 */
NULL, /* 15 */
"Sequence", /* 16 */
"Set", /* 17 */
NULL, /* 18 */
"PrintableString", /* 19 */
NULL, /* 20 */
NULL, /* 21 */
"IA5String", /* 22 */
"UTCTime", /* 23 */
"GeneralizedTime", /* 24 */
NULL, /* 25 */
"VisibleString", /* 26 */
"GeneralString" /* 27 */
};
static int
static size_t
loop (unsigned char *buf, size_t len, int indent)
{
unsigned char *start_buf = buf;
while (len > 0) {
int ret;
Der_class class;
@@ -93,7 +58,9 @@ loop (unsigned char *buf, size_t len, int indent)
int tag;
size_t sz;
size_t length;
int i;
size_t loop_length = 0;
int end_tag = 0;
const char *tagname;
ret = der_get_tag (buf, len, &class, &type, &tag, &sz);
if (ret)
@@ -103,62 +70,99 @@ loop (unsigned char *buf, size_t len, int indent)
(unsigned)sz, (unsigned)len);
buf += sz;
len -= sz;
for (i = 0; i < indent; ++i)
printf (" ");
printf ("%s %s ", class_names[class], type_names[type]);
if (tag_names[tag])
printf ("%s = ", tag_names[tag]);
if (indent_flag) {
int i;
for (i = 0; i < indent; ++i)
printf (" ");
}
printf ("%s %s ", der_get_class_name(class), der_get_type_name(type));
tagname = der_get_tag_name(tag);
if (class == ASN1_C_UNIV && tagname != NULL)
printf ("%s = ", tagname);
else
printf ("tag %d = ", tag);
ret = der_get_length (buf, len, &length, &sz);
if (ret)
errx (1, "der_get_tag: %s", error_message (ret));
if (sz > len)
errx (1, "unreasonable tag length (%u) > %u",
(unsigned)sz, (unsigned)len);
buf += sz;
len -= sz;
if (class == ASN1_C_CONTEXT) {
printf ("[%d]\n", tag);
loop (buf, length, indent);
if (length == ASN1_INDEFINITE) {
if ((class == ASN1_C_UNIV && type == PRIM && tag == UT_OctetString) ||
(class == ASN1_C_CONTEXT && type == CONS) ||
(class == ASN1_C_UNIV && type == CONS && tag == UT_Sequence) ||
(class == ASN1_C_UNIV && type == CONS && tag == UT_Set)) {
printf("*INDEFINITE FORM*");
} else {
fflush(stdout);
errx(1, "indef form used on unsupported object");
}
end_tag = 1;
if (indefinite_form_loop > indefinite_form_loop_max)
errx(1, "indefinite form used recursively more then %lu "
"times, aborting", indefinite_form_loop_max);
indefinite_form_loop++;
length = len;
} else if (length > len) {
printf("\n");
fflush(stdout);
errx (1, "unreasonable inner length (%u) > %u",
(unsigned)length, (unsigned)len);
}
if (class == ASN1_C_CONTEXT || class == ASN1_C_APPL) {
printf ("%d bytes [%d]\n", length, tag);
if (type == CONS)
loop_length = loop (buf, length, indent + 2);
} else if (class == ASN1_C_UNIV) {
switch (tag) {
case UT_EndOfContent:
printf (" INDEFINITE length was %lu\n",
(unsigned long)(buf - start_buf));
break;
case UT_Set :
case UT_Sequence :
printf ("{\n");
loop (buf, length, indent + 2);
for (i = 0; i < indent; ++i)
printf (" ");
printf ("}\n");
printf ("%lu bytes {\n", (unsigned long)length);
loop_length = loop (buf, length, indent + 2);
if (indent_flag) {
int i;
for (i = 0; i < indent; ++i)
printf (" ");
printf ("}\n");
} else
printf ("} indent = %d\n", indent / 2);
break;
case UT_Integer : {
int val;
ret = der_get_int (buf, length, &val, NULL);
if (ret)
errx (1, "der_get_int: %s", error_message (ret));
printf ("integer %d\n", val);
if (length <= sizeof(val)) {
ret = der_get_integer (buf, length, &val, NULL);
if (ret)
errx (1, "der_get_integer: %s", error_message (ret));
printf ("integer %d\n", val);
} else {
printf ("BIG NUM integer: length %d\n", length);
}
break;
}
case UT_OctetString : {
heim_octet_string str;
int i;
unsigned char *uc;
ret = der_get_octet_string (buf, length, &str, NULL);
if (ret)
errx (1, "der_get_octet_string: %s", error_message (ret));
printf ("(length %lu)%s", (unsigned long)str.length,
str.length > 0 ? ", " : "");
printf ("(length %lu), ", (unsigned long)length);
uc = (unsigned char *)str.data;
length = str.length;
if (length > 16)
length = 16;
for (i = 0; i < length; ++i)
for (i = 0; i < min(16,length); ++i)
printf ("%02x", uc[i]);
printf ("\n");
free (str.data);
break;
}
case UT_GeneralizedTime :
case UT_IA5String:
case UT_UTF8String :
case UT_GeneralString : {
heim_general_string str;
@@ -172,6 +176,7 @@ loop (unsigned char *buf, size_t len, int indent)
}
case UT_OID: {
heim_oid o;
int i;
ret = der_get_oid(buf, length, &o, NULL);
if (ret)
@@ -185,9 +190,9 @@ loop (unsigned char *buf, size_t len, int indent)
break;
}
case UT_Enumerated: {
unsigned num;
int num;
ret = der_get_int (buf, length, &num, NULL);
ret = der_get_integer (buf, length, &num, NULL);
if (ret)
errx (1, "der_get_enum: %s", error_message (ret));
@@ -199,6 +204,17 @@ loop (unsigned char *buf, size_t len, int indent)
break;
}
}
if (end_tag) {
if (loop_length == 0)
errx(1, "zero length INDEFINITE data ? indent = %d\n",
indent / 2);
if (loop_length < length)
length = loop_length;
if (indefinite_form_loop == 0)
errx(1, "internal error in indefinite form loop detection");
indefinite_form_loop--;
} else if (loop_length)
errx(1, "internal error for INDEFINITE form");
buf += length;
len -= length;
}
@@ -219,21 +235,20 @@ doit (const char *filename)
if (fstat (fd, &sb) < 0)
err (1, "stat %s", filename);
len = sb.st_size;
buf = malloc (len);
if (buf == NULL)
err (1, "malloc %u", (unsigned)len);
buf = emalloc (len);
if (read (fd, buf, len) != len)
errx (1, "read failed");
close (fd);
ret = loop (buf, len, 0);
free (buf);
return ret;
return 0;
}
static int version_flag;
static int help_flag;
struct getargs args[] = {
{ "indent", 0, arg_negative_flag, &indent_flag },
{ "version", 0, arg_flag, &version_flag },
{ "help", 0, arg_flag, &help_flag }
};
@@ -249,11 +264,11 @@ usage(int code)
int
main(int argc, char **argv)
{
int optidx = 0;
int optind = 0;
setprogname (argv[0]);
initialize_asn1_error_table ();
if(getarg(args, num_args, argc, argv, &optidx))
if(getarg(args, num_args, argc, argv, &optind))
usage(1);
if(help_flag)
usage(0);
@@ -261,8 +276,8 @@ main(int argc, char **argv)
print_version(NULL);
exit(0);
}
argv += optidx;
argc -= optidx;
argv += optind;
argc -= optind;
if (argc != 1)
usage (1);
return doit (argv[0]);

167
lib/asn1/asn1_queue.h Normal file
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).
* All rights reserved.
*
@@ -34,6 +34,9 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <stdio.h>
#include <string.h>
#include <err.h>
@@ -43,6 +46,107 @@
RCSID("$Id$");
struct map_page {
void *start;
size_t size;
void *data_start;
size_t data_size;
enum map_type type;
};
/* #undef HAVE_MMAP */
void *
map_alloc(enum map_type type, const void *buf,
size_t size, struct map_page **map)
{
#ifndef HAVE_MMAP
unsigned char *p;
*map = ecalloc(1, sizeof(**map));
p = emalloc(size + 2);
(*map)->type = type;
(*map)->start = p;
(*map)->size = size + 2;
p[0] = 0xff;
p[(*map)->size] = 0xff;
(*map)->data_start = p + 1;
#else
unsigned char *p;
int flags, ret, fd;
size_t pagesize = getpagesize();
*map = ecalloc(1, sizeof(**map));
(*map)->type = type;
#ifdef MAP_ANON
flags = MAP_ANON;
fd = -1;
#else
flags = 0;
fd = open ("/dev/zero", O_RDONLY);
if(fd < 0)
err (1, "open /dev/zero");
#endif
flags |= MAP_PRIVATE;
(*map)->size = size + pagesize - (size % pagesize) + pagesize * 2;
p = (char *)mmap(0, (*map)->size, PROT_READ | PROT_WRITE,
flags, fd, 0);
if (p == (unsigned char *)MAP_FAILED)
err (1, "mmap");
(*map)->start = p;
ret = mprotect (p, pagesize, 0);
if (ret < 0)
err (1, "mprotect");
ret = mprotect (p + (*map)->size - pagesize, pagesize, 0);
if (ret < 0)
err (1, "mprotect");
switch (type) {
case OVERRUN:
(*map)->data_start = p + (*map)->size - pagesize - size;
break;
case UNDERRUN:
(*map)->data_start = p + pagesize;
break;
default:
abort();
}
#endif
(*map)->data_size = size;
if (buf)
memcpy((*map)->data_start, buf, size);
return (*map)->data_start;
}
void
map_free(struct map_page *map, const char *test_name, const char *map_name)
{
#ifndef HAVE_MMAP
unsigned char *p = map->start;
if (p[0] != 0xff)
errx(1, "%s: %s underrun %x\n", test_name, map_name, p[0]);
if (p[map->size] != 0xff)
errx(1, "%s: %s overrun %x\n", test_name, map_name, p[map->size - 1]);
free(map->start);
#else
int ret;
ret = munmap (map->start, map->size);
if (ret < 0)
err (1, "munmap");
#endif
free(map);
}
static void
print_bytes (unsigned const char *buf, size_t len)
{
@@ -52,6 +156,31 @@ print_bytes (unsigned const char *buf, size_t len)
printf ("%02x ", buf[i]);
}
#ifndef MAP_FAILED
#define MAP_FAILED (-1)
#endif
static char *current_test = "<uninit>";
static char *current_state = "<uninit>";
static RETSIGTYPE
segv_handler(int sig)
{
int fd;
char msg[] = "SIGSEGV i current test: ";
fd = open("/dev/stdout", O_WRONLY, 0600);
if (fd >= 0) {
write(fd, msg, sizeof(msg));
write(fd, current_test, strlen(current_test));
write(fd, " ", 1);
write(fd, current_state, strlen(current_state));
write(fd, "\n", 1);
close(fd);
}
_exit(1);
}
int
generic_test (const struct test_case *tests,
unsigned ntests,
@@ -59,67 +188,181 @@ generic_test (const struct test_case *tests,
int (*encode)(unsigned char *, size_t, void *, size_t *),
int (*length)(void *),
int (*decode)(unsigned char *, size_t, void *, size_t *),
int (*free_data)(void *),
int (*cmp)(void *a, void *b))
{
unsigned char buf[4711];
unsigned char *buf, *buf2;
int i;
int failures = 0;
void *val = malloc (data_size);
void *data;
struct map_page *data_map, *buf_map, *buf2_map;
if (data_size != 0 && val == NULL)
err (1, "malloc");
struct sigaction sa, osa;
for (i = 0; i < ntests; ++i) {
int ret;
size_t sz, consumed_sz, length_sz;
unsigned char *beg;
size_t sz, consumed_sz, length_sz, buf_sz;
ret = (*encode) (buf + sizeof(buf) - 1, sizeof(buf),
current_test = tests[i].name;
current_state = "init";
sigemptyset (&sa.sa_mask);
sa.sa_flags = 0;
#ifdef SA_RESETHAND
sa.sa_flags |= SA_RESETHAND;
#endif
sa.sa_handler = segv_handler;
sigaction (SIGSEGV, &sa, &osa);
data = map_alloc(OVERRUN, NULL, data_size, &data_map);
buf_sz = tests[i].byte_len;
buf = map_alloc(UNDERRUN, NULL, buf_sz, &buf_map);
current_state = "encode";
ret = (*encode) (buf + buf_sz - 1, buf_sz,
tests[i].val, &sz);
beg = buf + sizeof(buf) - sz;
if (ret != 0) {
printf ("encoding of %s failed\n", tests[i].name);
printf ("encoding of %s failed %d\n", tests[i].name, ret);
++failures;
continue;
}
if (sz != tests[i].byte_len) {
printf ("encoding of %s has wrong len (%lu != %lu)\n",
tests[i].name,
(unsigned long)sz, (unsigned long)tests[i].byte_len);
++failures;
continue;
}
current_state = "length";
length_sz = (*length) (tests[i].val);
if (sz != length_sz) {
printf ("length for %s is bad (%lu != %lu)\n",
tests[i].name, (unsigned long)length_sz, (unsigned long)sz);
++failures;
continue;
}
if (memcmp (beg, tests[i].bytes, tests[i].byte_len) != 0) {
current_state = "memcmp";
if (memcmp (buf, tests[i].bytes, tests[i].byte_len) != 0) {
printf ("encoding of %s has bad bytes:\n"
"correct: ", tests[i].name);
print_bytes (tests[i].bytes, tests[i].byte_len);
printf ("\nactual: ");
print_bytes (beg, sz);
print_bytes (buf, sz);
printf ("\n");
++failures;
continue;
}
ret = (*decode) (beg, sz, val, &consumed_sz);
buf2 = map_alloc(OVERRUN, buf, sz, &buf2_map);
current_state = "decode";
ret = (*decode) (buf2, sz, data, &consumed_sz);
if (ret != 0) {
printf ("decoding of %s failed\n", tests[i].name);
printf ("decoding of %s failed %d\n", tests[i].name, ret);
++failures;
continue;
}
if (sz != consumed_sz) {
printf ("different length decoding %s (%ld != %ld)\n",
tests[i].name,
(unsigned long)sz, (unsigned long)consumed_sz);
++failures;
continue;
}
if ((*cmp)(val, tests[i].val) != 0) {
current_state = "cmp";
if ((*cmp)(data, tests[i].val) != 0) {
printf ("%s: comparison failed\n", tests[i].name);
++failures;
continue;
}
current_state = "free";
if (free_data)
(*free_data)(data);
current_state = "free";
map_free(buf_map, tests[i].name, "encode");
map_free(buf2_map, tests[i].name, "decode");
map_free(data_map, tests[i].name, "data");
sigaction (SIGSEGV, &osa, NULL);
}
free (val);
current_state = "done";
return failures;
}
/*
* check for failures
*
* a test size (byte_len) of -1 means that the test tries to trigger a
* integer overflow (and later a malloc of to little memory), just
* allocate some memory and hope that is enough for that test.
*/
int
generic_decode_fail (const struct test_case *tests,
unsigned ntests,
size_t data_size,
int (*decode)(unsigned char *, size_t, void *, size_t *))
{
unsigned char *buf;
int i;
int failures = 0;
void *data;
struct map_page *data_map, *buf_map;
struct sigaction sa, osa;
for (i = 0; i < ntests; ++i) {
int ret;
size_t sz;
const void *bytes;
current_test = tests[i].name;
current_state = "init";
sigemptyset (&sa.sa_mask);
sa.sa_flags = 0;
#ifdef SA_RESETHAND
sa.sa_flags |= SA_RESETHAND;
#endif
sa.sa_handler = segv_handler;
sigaction (SIGSEGV, &sa, &osa);
data = map_alloc(OVERRUN, NULL, data_size, &data_map);
if (tests[i].byte_len != -1) {
sz = tests[i].byte_len;
bytes = tests[i].bytes;
} else {
sz = 4096;
bytes = NULL;
}
buf = map_alloc(OVERRUN, bytes, sz, &buf_map);
if (tests[i].byte_len == -1)
memset(buf, 0, sz);
current_state = "decode";
ret = (*decode) (buf, tests[i].byte_len, data, &sz);
if (ret == 0) {
printf ("sucessfully decoded %s\n", tests[i].name);
++failures;
continue;
}
current_state = "free";
if (buf)
map_free(buf_map, tests[i].name, "encode");
map_free(data_map, tests[i].name, "data");
sigaction (SIGSEGV, &osa, NULL);
}
current_state = "done";
return failures;
}

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).
* All rights reserved.
*
@@ -41,6 +41,7 @@ struct test_case {
typedef int (*generic_encode)(unsigned char *, size_t, void *, size_t *);
typedef int (*generic_length)(void *);
typedef int (*generic_decode)(unsigned char *, size_t, void *, size_t *);
typedef int (*generic_free)(void *);
int
generic_test (const struct test_case *tests,
@@ -49,5 +50,21 @@ generic_test (const struct test_case *tests,
int (*encode)(unsigned char *, size_t, void *, size_t *),
int (*length)(void *),
int (*decode)(unsigned char *, size_t, void *, size_t *),
int (*free_data)(void *),
int (*cmp)(void *a, void *b));
int
generic_decode_fail(const struct test_case *tests,
unsigned ntests,
size_t data_size,
int (*decode)(unsigned char *, size_t, void *, size_t *));
struct map_page;
enum map_type { OVERRUN, UNDERRUN };
struct map_page;
void * map_alloc(enum map_type, const void *, size_t, struct map_page **);
void map_free(struct map_page *, const char *, const char *);

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).
* All rights reserved.
*
@@ -56,17 +56,17 @@ static int
test_integer (void)
{
struct test_case tests[] = {
{NULL, 3, "\x02\x01\x00"},
{NULL, 3, "\x02\x01\x7f"},
{NULL, 4, "\x02\x02\x00\x80"},
{NULL, 4, "\x02\x02\x01\x00"},
{NULL, 3, "\x02\x01\x80"},
{NULL, 4, "\x02\x02\xff\x7f"},
{NULL, 3, "\x02\x01\xff"},
{NULL, 4, "\x02\x02\xff\x01"},
{NULL, 4, "\x02\x02\x00\xff"},
{NULL, 6, "\x02\x04\x80\x00\x00\x00"},
{NULL, 6, "\x02\x04\x7f\xff\xff\xff"}
{NULL, 1, "\x00"},
{NULL, 1, "\x7f"},
{NULL, 2, "\x00\x80"},
{NULL, 2, "\x01\x00"},
{NULL, 1, "\x80"},
{NULL, 2, "\xff\x7f"},
{NULL, 1, "\xff"},
{NULL, 2, "\xff\x01"},
{NULL, 2, "\x00\xff"},
{NULL, 4, "\x80\x00\x00\x00"},
{NULL, 4, "\x7f\xff\xff\xff"}
};
int values[] = {0, 127, 128, 256, -128, -129, -1, -255, 255,
@@ -77,21 +77,23 @@ test_integer (void)
for (i = 0; i < ntests; ++i) {
tests[i].val = &values[i];
asprintf (&tests[i].name, "integer %d", values[i]);
if (tests[i].name == NULL)
errx(1, "malloc");
}
return generic_test (tests, ntests, sizeof(int),
(generic_encode)encode_integer,
(generic_encode)der_put_integer,
(generic_length) length_integer,
(generic_decode)decode_integer,
(generic_decode)der_get_integer,
(generic_free)NULL,
cmp_integer);
}
static int
test_one_int(int val)
{
int ret, dval;
int len, ret, len_len, dval;
unsigned char *buf;
size_t len_len, len;
len = _heim_len_int(val);
@@ -101,25 +103,25 @@ test_one_int(int val)
buf[len + 1] = '\xff';
memset(buf + 1, 0, len);
ret = der_put_int(buf + 1 + len - 1, len, val, &len_len);
ret = der_put_integer(buf + 1 + len - 1, len, &val, &len_len);
if (ret) {
printf("integer %d encode failed %d\n", val, ret);
return 1;
}
if (len != len_len) {
printf("integer %d encode fail with %d len %lu, result len %lu\n",
val, ret, (unsigned long)len, (unsigned long)len_len);
printf("integer %d encode fail with %d len %d, result len %d\n",
val, ret, len, len_len);
return 1;
}
ret = der_get_int(buf + 1, len, &dval, &len_len);
ret = der_get_integer(buf + 1, len, &dval, &len_len);
if (ret) {
printf("integer %d decode failed %d\n", val, ret);
return 1;
}
if (len != len_len) {
printf("integer %d decoded diffrent len %lu != %lu",
val, (unsigned long)len, (unsigned long)len_len);
printf("integer %d decoded diffrent len %d != %d",
val, len, len_len);
return 1;
}
if (val != dval) {
@@ -174,14 +176,14 @@ static int
test_unsigned (void)
{
struct test_case tests[] = {
{NULL, 3, "\x02\x01\x00"},
{NULL, 3, "\x02\x01\x7f"},
{NULL, 4, "\x02\x02\x00\x80"},
{NULL, 4, "\x02\x02\x01\x00"},
{NULL, 4, "\x02\x02\x02\x00"},
{NULL, 5, "\x02\x03\x00\x80\x00"},
{NULL, 7, "\x02\x05\x00\x80\x00\x00\x00"},
{NULL, 6, "\x02\x04\x7f\xff\xff\xff"}
{NULL, 1, "\x00"},
{NULL, 1, "\x7f"},
{NULL, 2, "\x00\x80"},
{NULL, 2, "\x01\x00"},
{NULL, 2, "\x02\x00"},
{NULL, 3, "\x00\x80\x00"},
{NULL, 5, "\x00\x80\x00\x00\x00"},
{NULL, 4, "\x7f\xff\xff\xff"}
};
unsigned int values[] = {0, 127, 128, 256, 512, 32768,
@@ -192,12 +194,15 @@ test_unsigned (void)
for (i = 0; i < ntests; ++i) {
tests[i].val = &values[i];
asprintf (&tests[i].name, "unsigned %u", values[i]);
if (tests[i].name == NULL)
errx(1, "malloc");
}
return generic_test (tests, ntests, sizeof(int),
(generic_encode)encode_unsigned,
(generic_length) length_unsigned,
(generic_decode)decode_unsigned,
(generic_encode)der_put_unsigned,
(generic_length)length_unsigned,
(generic_decode)der_get_unsigned,
(generic_free)NULL,
cmp_unsigned);
}
@@ -219,20 +224,63 @@ test_octet_string (void)
heim_octet_string s1 = {8, "\x01\x23\x45\x67\x89\xab\xcd\xef"};
struct test_case tests[] = {
{NULL, 10, "\x04\x08\x01\x23\x45\x67\x89\xab\xcd\xef"}
{NULL, 8, "\x01\x23\x45\x67\x89\xab\xcd\xef"}
};
int ntests = sizeof(tests) / sizeof(*tests);
tests[0].val = &s1;
asprintf (&tests[0].name, "a octet string");
if (tests[0].name == NULL)
errx(1, "malloc");
return generic_test (tests, ntests, sizeof(heim_octet_string),
(generic_encode)encode_octet_string,
(generic_encode)der_put_octet_string,
(generic_length)length_octet_string,
(generic_decode)decode_octet_string,
(generic_decode)der_get_octet_string,
(generic_free)free_octet_string,
cmp_octet_string);
}
static int
cmp_bmp_string (void *a, void *b)
{
heim_bmp_string *oa = (heim_bmp_string *)a;
heim_bmp_string *ob = (heim_bmp_string *)b;
return heim_bmp_string_cmp(oa, ob);
}
static int
test_bmp_string (void)
{
uint16_t d1[] = { 32 };
heim_bmp_string s1 = { 1, d1 };
uint16_t d2[] = { 32, 32 };
heim_bmp_string s2 = { 2, d2 };
struct test_case tests[] = {
{NULL, 2, "\x00\x20"},
{NULL, 4, "\x00\x20\x00\x20"}
};
int ntests = sizeof(tests) / sizeof(*tests);
tests[0].val = &s1;
asprintf (&tests[0].name, "a bmp string");
if (tests[0].name == NULL)
errx(1, "malloc");
tests[1].val = &s2;
asprintf (&tests[1].name, "second bmp string");
if (tests[1].name == NULL)
errx(1, "malloc");
return generic_test (tests, ntests, sizeof(heim_bmp_string),
(generic_encode)der_put_bmp_string,
(generic_length)length_bmp_string,
(generic_decode)der_get_bmp_string,
(generic_free)free_bmp_string,
cmp_bmp_string);
}
static int
cmp_general_string (void *a, void *b)
{
@@ -248,17 +296,20 @@ test_general_string (void)
unsigned char *s1 = "Test User 1";
struct test_case tests[] = {
{NULL, 13, "\x1b\x0b\x54\x65\x73\x74\x20\x55\x73\x65\x72\x20\x31"}
{NULL, 11, "\x54\x65\x73\x74\x20\x55\x73\x65\x72\x20\x31"}
};
int ntests = sizeof(tests) / sizeof(*tests);
tests[0].val = &s1;
asprintf (&tests[0].name, "the string \"%s\"", s1);
if (tests[0].name == NULL)
errx(1, "malloc");
return generic_test (tests, ntests, sizeof(unsigned char *),
(generic_encode)encode_general_string,
(generic_encode)der_put_general_string,
(generic_length)length_general_string,
(generic_decode)decode_general_string,
(generic_decode)der_get_general_string,
(generic_free)free_general_string,
cmp_general_string);
}
@@ -275,8 +326,8 @@ static int
test_generalized_time (void)
{
struct test_case tests[] = {
{NULL, 17, "\x18\x0f""19700101000000Z"},
{NULL, 17, "\x18\x0f""19851106210627Z"}
{NULL, 15, "19700101000000Z"},
{NULL, 15, "19851106210627Z"}
};
time_t values[] = {0, 500159187};
int i;
@@ -285,15 +336,211 @@ test_generalized_time (void)
for (i = 0; i < ntests; ++i) {
tests[i].val = &values[i];
asprintf (&tests[i].name, "time %d", (int)values[i]);
if (tests[i].name == NULL)
errx(1, "malloc");
}
return generic_test (tests, ntests, sizeof(time_t),
(generic_encode)encode_generalized_time,
(generic_encode)der_put_generalized_time,
(generic_length)length_generalized_time,
(generic_decode)decode_generalized_time,
(generic_decode)der_get_generalized_time,
(generic_free)NULL,
cmp_generalized_time);
}
static int
test_cmp_oid (void *a, void *b)
{
return heim_oid_cmp((heim_oid *)a, (heim_oid *)b);
}
static int
test_oid (void)
{
struct test_case tests[] = {
{NULL, 2, "\x29\x01"},
{NULL, 1, "\x29"},
{NULL, 2, "\xff\x01"},
{NULL, 1, "\xff"}
};
unsigned oid_comp1[] = { 1, 1, 1 };
unsigned oid_comp2[] = { 1, 1 };
unsigned oid_comp3[] = { 6, 15, 1 };
unsigned oid_comp4[] = { 6, 15 };
heim_oid values[] = {
{ 3, oid_comp1 },
{ 2, oid_comp2 },
{ 3, oid_comp3 },
{ 2, oid_comp4 }
};
int i;
int ntests = sizeof(tests) / sizeof(*tests);
for (i = 0; i < ntests; ++i) {
tests[i].val = &values[i];
asprintf (&tests[i].name, "oid %d", i);
if (tests[i].name == NULL)
errx(1, "malloc");
}
return generic_test (tests, ntests, sizeof(heim_oid),
(generic_encode)der_put_oid,
(generic_length)length_oid,
(generic_decode)der_get_oid,
(generic_free)free_oid,
test_cmp_oid);
}
static int
check_fail_unsigned(void)
{
struct test_case tests[] = {
{NULL, sizeof(unsigned) + 1,
"\x01\x01\x01\x01\x01\x01\x01\x01\x01", "data overrun" }
};
int ntests = sizeof(tests) / sizeof(*tests);
return generic_decode_fail(tests, ntests, sizeof(unsigned),
(generic_decode)der_get_unsigned);
}
static int
check_fail_integer(void)
{
struct test_case tests[] = {
{NULL, sizeof(int) + 1,
"\x01\x01\x01\x01\x01\x01\x01\x01\x01", "data overrun" }
};
int ntests = sizeof(tests) / sizeof(*tests);
return generic_decode_fail(tests, ntests, sizeof(int),
(generic_decode)der_get_integer);
}
static int
check_fail_length(void)
{
struct test_case tests[] = {
{NULL, 0, "", "empty input data"},
{NULL, 1, "\x82", "internal length overrun" }
};
int ntests = sizeof(tests) / sizeof(*tests);
return generic_decode_fail(tests, ntests, sizeof(size_t),
(generic_decode)der_get_length);
}
static int
check_fail_boolean(void)
{
struct test_case tests[] = {
{NULL, 0, "", "empty input data"}
};
int ntests = sizeof(tests) / sizeof(*tests);
return generic_decode_fail(tests, ntests, sizeof(int),
(generic_decode)der_get_boolean);
}
static int
check_fail_general_string(void)
{
struct test_case tests[] = {
{NULL, -1, "", "over sized buffer"}
};
int ntests = sizeof(tests) / sizeof(*tests);
return generic_decode_fail(tests, ntests, sizeof(heim_general_string),
(generic_decode)der_get_general_string);
}
static int
check_fail_bmp_string(void)
{
struct test_case tests[] = {
{NULL, 1, "\x00", "odd length bmpstring"},
{NULL, -1, "\x00", "over sized data"}
};
int ntests = sizeof(tests) / sizeof(*tests);
return generic_decode_fail(tests, ntests, sizeof(heim_bmp_string),
(generic_decode)der_get_bmp_string);
}
static int
check_fail_universal_string(void)
{
struct test_case tests[] = {
{NULL, 1, "\x00", "x & 3 == 1 universal string"},
{NULL, 2, "\x00\x00", "x & 3 == 2 universal string"},
{NULL, 3, "\x00\x00\x00", "x & 3 == 3 universal string"},
{NULL, 5, "\x00\x00\x00\x00\x00", "x & 3 == 1 universal string"},
{NULL, 6, "\x00\x00\x00\x00\x00\x00", "x & 3 == 2 universal string"},
{NULL, 7, "\x00\x00\x00\x00\x00\x00\x00", "x & 3 == 3 universal string"},
{NULL, -1, "\x00", "over sized data"}
};
int ntests = sizeof(tests) / sizeof(*tests);
return generic_decode_fail(tests, ntests, sizeof(heim_universal_string),
(generic_decode)der_get_universal_string);
}
static int
check_fail_heim_integer(void)
{
struct test_case tests[] = {
{NULL, -1, "\x00", "over sized data"}
};
int ntests = sizeof(tests) / sizeof(*tests);
return generic_decode_fail(tests, ntests, sizeof(heim_integer),
(generic_decode)der_get_heim_integer);
}
static int
check_fail_generalized_time(void)
{
struct test_case tests[] = {
{NULL, 1, "\x00", "no time"},
{NULL, -1, "\x00", "over sized data"}
};
int ntests = sizeof(tests) / sizeof(*tests);
return generic_decode_fail(tests, ntests, sizeof(time_t),
(generic_decode)der_get_generalized_time);
}
static int
check_fail_oid(void)
{
struct test_case tests[] = {
{NULL, 0, "", "empty input data"},
{NULL, 2, "\x00\x80", "last byte continuation" },
{NULL, 11, "\x00\x81\x80\x80\x80\x80\x80\x80\x80\x80\x00",
"oid element overflow" },
{NULL, -1, "", "over sized buffer" }
};
int ntests = sizeof(tests) / sizeof(*tests);
return generic_decode_fail(tests, ntests, sizeof(heim_oid),
(generic_decode)der_get_oid);
}
static int
check_fail_bitstring(void)
{
struct test_case tests[] = {
{NULL, 0, "", "empty input data"},
{NULL, 1, "\x08", "larger then 8 bits trailer"},
{NULL, 1, "\x01", "to few bytes for bits"},
{NULL, -1, "", "length to short"}
};
int ntests = sizeof(tests) / sizeof(*tests);
return generic_decode_fail(tests, ntests, sizeof(heim_bit_string),
(generic_decode)der_get_bit_string);
}
int
main(int argc, char **argv)
{
@@ -303,8 +550,22 @@ main(int argc, char **argv)
ret += test_integer_more();
ret += test_unsigned ();
ret += test_octet_string ();
ret += test_bmp_string ();
ret += test_general_string ();
ret += test_generalized_time ();
ret += test_oid ();
ret += check_fail_unsigned();
ret += check_fail_integer();
ret += check_fail_length();
ret += check_fail_boolean();
ret += check_fail_general_string();
ret += check_fail_bmp_string();
ret += check_fail_universal_string();
ret += check_fail_heim_integer();
ret += check_fail_generalized_time();
ret += check_fail_oid();
ret += check_fail_bitstring();
return ret;
}

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).
* All rights reserved.
*
@@ -43,16 +43,26 @@
#include <asn1_err.h>
#include <der.h>
#include <krb5_asn1.h>
#include <heim_asn1.h>
#include <rfc2459_asn1.h>
#include <test_asn1.h>
#include "check-common.h"
RCSID("$Id$");
static char *lha_princ[] = { "lha" };
static char *lha_principal[] = { "lha" };
static char *lharoot_princ[] = { "lha", "root" };
static char *datan_princ[] = { "host", "nutcracker.e.kth.se" };
static char *nada_tgt_principal[] = { "krbtgt", "NADA.KTH.SE" };
#define IF_OPT_COMPARE(ac,bc,e) \
if (((ac)->e == NULL && (bc)->e != NULL) || (((ac)->e != NULL && (bc)->e == NULL))) return 1; if ((ab)->e)
#define COMPARE_OPT_STRING(ac,bc,e) \
do { if (strcmp(*(ac)->e, *(bc)->e) != 0) return 1; } while(0)
#define COMPARE_OPT_OCTECT_STRING(ac,bc,e) \
do { if ((ac)->e->length != (bc)->e->length || memcmp((ac)->e->data, (bc)->e->data, (ac)->e->length) != 0) return 1; } while(0)
#define COMPARE_STRING(ac,bc,e) \
do { if (strcmp((ac)->e, (bc)->e) != 0) return 1; } while(0)
#define COMPARE_INTEGER(ac,bc,e) \
@@ -101,7 +111,7 @@ test_principal (void)
Principal values[] = {
{ { KRB5_NT_PRINCIPAL, { 1, lha_princ } }, "SU.SE" },
{ { KRB5_NT_PRINCIPAL, { 1, lha_principal } }, "SU.SE" },
{ { KRB5_NT_PRINCIPAL, { 2, lharoot_princ } }, "SU.SE" },
{ { KRB5_NT_SRV_HST, { 2, datan_princ } }, "E.KTH.SE" }
};
@@ -117,6 +127,7 @@ test_principal (void)
(generic_encode)encode_Principal,
(generic_length)length_Principal,
(generic_decode)decode_Principal,
(generic_free)free_Principal,
cmp_principal);
}
@@ -161,7 +172,7 @@ test_authenticator (void)
};
Authenticator values[] = {
{ 5, "E.KTH.SE", { KRB5_NT_PRINCIPAL, { 1, lha_princ } },
{ 5, "E.KTH.SE", { KRB5_NT_PRINCIPAL, { 1, lha_principal } },
NULL, 10, 99, NULL, NULL, NULL },
{ 5, "SU.SE", { KRB5_NT_PRINCIPAL, { 2, lharoot_princ } },
NULL, 292, 999, NULL, NULL, NULL }
@@ -178,111 +189,496 @@ test_authenticator (void)
(generic_encode)encode_Authenticator,
(generic_length)length_Authenticator,
(generic_decode)decode_Authenticator,
(generic_free)free_Authenticator,
cmp_authenticator);
}
static int
cmp_AuthorizationData (void *a, void *b)
cmp_KRB_ERROR (void *a, void *b)
{
AuthorizationData *aa = a;
AuthorizationData *ab = b;
KRB_ERROR *aa = a;
KRB_ERROR *ab = b;
int i;
COMPARE_INTEGER(aa,ab,len);
COMPARE_INTEGER(aa,ab,pvno);
COMPARE_INTEGER(aa,ab,msg_type);
IF_OPT_COMPARE(aa,ab,ctime) {
COMPARE_INTEGER(aa,ab,ctime);
}
IF_OPT_COMPARE(aa,ab,cusec) {
COMPARE_INTEGER(aa,ab,cusec);
}
COMPARE_INTEGER(aa,ab,stime);
COMPARE_INTEGER(aa,ab,susec);
COMPARE_INTEGER(aa,ab,error_code);
IF_OPT_COMPARE(aa,ab,crealm) {
COMPARE_OPT_STRING(aa,ab,crealm);
}
#if 0
IF_OPT_COMPARE(aa,ab,cname) {
COMPARE_OPT_STRING(aa,ab,cname);
}
#endif
COMPARE_STRING(aa,ab,realm);
COMPARE_INTEGER(aa,ab,sname.name_string.len);
for (i = 0; i < aa->sname.name_string.len; i++)
COMPARE_STRING(aa,ab,sname.name_string.val[i]);
IF_OPT_COMPARE(aa,ab,e_text) {
COMPARE_OPT_STRING(aa,ab,e_text);
}
IF_OPT_COMPARE(aa,ab,e_data) {
// COMPARE_OPT_OCTECT_STRING(aa,ab,e_data);
}
return 0;
}
static char static_buf512[512];
static int
test_AuthorizationData (void)
test_krb_error (void)
{
struct test_case tests[] = {
{ NULL, 14,
{ NULL, 127,
(unsigned char*)
"\x30\x0c\x30\x0a\xa0\x03\x02\x01\x01\xa1\x03\x04\x01\x00"
"\x7e\x7d\x30\x7b\xa0\x03\x02\x01\x05\xa1\x03\x02\x01\x1e\xa4\x11"
"\x18\x0f\x32\x30\x30\x33\x31\x31\x32\x34\x30\x30\x31\x31\x31\x39"
"\x5a\xa5\x05\x02\x03\x04\xed\xa5\xa6\x03\x02\x01\x1f\xa7\x0d\x1b"
"\x0b\x4e\x41\x44\x41\x2e\x4b\x54\x48\x2e\x53\x45\xa8\x10\x30\x0e"
"\xa0\x03\x02\x01\x01\xa1\x07\x30\x05\x1b\x03\x6c\x68\x61\xa9\x0d"
"\x1b\x0b\x4e\x41\x44\x41\x2e\x4b\x54\x48\x2e\x53\x45\xaa\x20\x30"
"\x1e\xa0\x03\x02\x01\x01\xa1\x17\x30\x15\x1b\x06\x6b\x72\x62\x74"
"\x67\x74\x1b\x0b\x4e\x41\x44\x41\x2e\x4b\x54\x48\x2e\x53\x45",
"KRB-ERROR Test 1"
}
};
int ntests = sizeof(tests) / sizeof(*tests);
KRB_ERROR e1;
PrincipalName lhaprincipalname = { 1, { 1, lha_principal } };
PrincipalName tgtprincipalname = { 1, { 2, nada_tgt_principal } };
char *realm = "NADA.KTH.SE";
e1.pvno = 5;
e1.msg_type = 30;
e1.ctime = NULL;
e1.cusec = NULL;
e1.stime = 1069632679;
e1.susec = 322981;
e1.error_code = 31;
e1.crealm = &realm;
e1.cname = &lhaprincipalname;
e1.realm = "NADA.KTH.SE";
e1.sname = tgtprincipalname;
e1.e_text = NULL;
e1.e_data = NULL;
tests[0].val = &e1;
return generic_test (tests, ntests, sizeof(KRB_ERROR),
(generic_encode)encode_KRB_ERROR,
(generic_length)length_KRB_ERROR,
(generic_decode)decode_KRB_ERROR,
(generic_free)free_KRB_ERROR,
cmp_KRB_ERROR);
}
static int
cmp_Name (void *a, void *b)
{
/* XXX */
return 0;
}
static int
test_Name (void)
{
struct test_case tests[] = {
{ NULL, 35,
(unsigned char*)
"\x30\x21\x31\x1f\x30\x0b\x06\x03\x55\x04\x03\x13\x04\x4c\x6f\x76"
"\x65\x30\x10\x06\x03\x55\x04\x07\x13\x09\x53\x54\x4f\x43\x4b\x48"
"\x4f\x4c\x4d",
"Name CN=Love+L=STOCKHOLM"
},
{ NULL, 142,
{ NULL, 35,
(unsigned char*)
"\x30\x81\x8b\x30\x81\x88\xa0\x03\x02\x01\x01\xa1\x81\x80\x04\x7e"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
},
{ NULL, 132,
(unsigned char*)
"\x30\x81\x81\x30\x73\xa0\x03\x02\x01\x01\xa1\x6c\x04\x6a\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x30\x0a\xa0\x03\x02\x01\x01\xa1"
"\x03\x04\x01\x00"
},
{ NULL, 134,
(unsigned char*)
"\x30\x81\x83\x30\x74\xa0\x03\x02\x01\x01\xa1\x6d\x04\x6b\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x0b\xa0\x03\x02\x01\x01"
"\xa1\x04\x04\x02\x00\x00"
"\x30\x21\x31\x1f\x30\x0b\x06\x03\x55\x04\x03\x13\x04\x4c\x6f\x76"
"\x65\x30\x10\x06\x03\x55\x04\x07\x13\x09\x53\x54\x4f\x43\x4b\x48"
"\x4f\x4c\x4d",
"Name L=STOCKHOLM+CN=Love"
}
};
AuthorizationData values[] = {
{ 1, NULL },
{ 1, NULL },
{ 2, NULL },
{ 2, NULL }
int ntests = sizeof(tests) / sizeof(*tests);
Name n1, n2;
RelativeDistinguishedName rdn1[1];
RelativeDistinguishedName rdn2[1];
AttributeTypeAndValue atv1[2];
AttributeTypeAndValue atv2[2];
unsigned cmp_CN[] = { 2, 5, 4, 3 };
unsigned cmp_L[] = { 2, 5, 4, 7 };
/* n1 */
n1.element = choice_Name_rdnSequence;
n1.u.rdnSequence.val = rdn1;
n1.u.rdnSequence.len = sizeof(rdn1)/sizeof(rdn1[0]);
rdn1[0].val = atv1;
rdn1[0].len = sizeof(atv1)/sizeof(atv1[0]);
atv1[0].type.length = sizeof(cmp_CN)/sizeof(cmp_CN[0]);
atv1[0].type.components = cmp_CN;
atv1[0].value.element = choice_DirectoryString_printableString;
atv1[0].value.u.printableString = "Love";
atv1[1].type.length = sizeof(cmp_L)/sizeof(cmp_L[0]);
atv1[1].type.components = cmp_L;
atv1[1].value.element = choice_DirectoryString_printableString;
atv1[1].value.u.printableString = "STOCKHOLM";
/* n2 */
n2.element = choice_Name_rdnSequence;
n2.u.rdnSequence.val = rdn2;
n2.u.rdnSequence.len = sizeof(rdn2)/sizeof(rdn2[0]);
rdn2[0].val = atv2;
rdn2[0].len = sizeof(atv2)/sizeof(atv2[0]);
atv2[0].type.length = sizeof(cmp_L)/sizeof(cmp_L[0]);
atv2[0].type.components = cmp_L;
atv2[0].value.element = choice_DirectoryString_printableString;
atv2[0].value.u.printableString = "STOCKHOLM";
atv2[1].type.length = sizeof(cmp_CN)/sizeof(cmp_CN[0]);
atv2[1].type.components = cmp_CN;
atv2[1].value.element = choice_DirectoryString_printableString;
atv2[1].value.u.printableString = "Love";
/* */
tests[0].val = &n1;
tests[1].val = &n2;
return generic_test (tests, ntests, sizeof(Name),
(generic_encode)encode_Name,
(generic_length)length_Name,
(generic_decode)decode_Name,
(generic_free)free_Name,
cmp_Name);
}
#if 0
#include <openssl/bn.h>
static int
check_heim_integer(void)
{
heim_integer h;
BIGNUM *bn = BN_new();
unsigned char buf[10];
unsigned char buf2[10];
size_t len = sizeof(buf), size;
size_t len2 = sizeof(buf), size2;
int i, ret;
memset(buf, 0, sizeof(buf));
memset(buf2, 0, sizeof(buf2));
i = -123123;
BN_zero(bn);
if (i < 0)
BN_sub_word(bn, -i);
else
BN_add_word(bn, i);
h.negative = bn->neg;
h.length = BN_num_bytes(bn);
h.data = emalloc(h.length);
BN_bn2bin(bn, h.data);
printf("length = %d\n", h.length);
ret = der_put_heim_integer(buf + len - 1, len, &h, &size);
if (ret)
errx(1, "der_put_heim_integer: %d", ret);
ret = der_put_integer(buf2 + len - 1, len2, &i, &size2);
if (ret)
errx(1, "der_put_heim_integer: %d", ret);
if (size != size2)
errx(1, "size %lu != size2 %lu",
(unsigned long)size, (unsigned long)size2);
if (memcmp(buf + len - 1 - size,
buf2 + len - 1 - size,
size) != 0)
errx(1, "data not the same");
return 0;
}
#endif
static int
cmp_KeyUsage (void *a, void *b)
{
KeyUsage *aa = a;
KeyUsage *ab = b;
return KeyUsage2int(*aa) != KeyUsage2int(*ab);
}
static int
test_bit_string (void)
{
struct test_case tests[] = {
{ NULL, 4,
"\x03\x02\x07\x80",
"bitstring 1"
}
};
int ntests = sizeof(tests) / sizeof(*tests);
KeyUsage ku1;
memset(&ku1, 0, sizeof(ku1));
ku1.digitalSignature = 1;
tests[0].val = &ku1;
return generic_test (tests, ntests, sizeof(KeyUsage),
(generic_encode)encode_KeyUsage,
(generic_length)length_KeyUsage,
(generic_decode)decode_KeyUsage,
(generic_free)free_KeyUsage,
cmp_KeyUsage);
}
static int
cmp_TESTLargeTag (void *a, void *b)
{
TESTLargeTag *aa = a;
TESTLargeTag *ab = b;
COMPARE_INTEGER(aa,ab,foo);
return 0;
}
static int
test_large_tag (void)
{
struct test_case tests[] = {
{ NULL, 8, "\x30\x06\xbf\x7f\x03\x02\x01\x01", "large tag 1" }
};
int ntests = sizeof(tests) / sizeof(*tests);
TESTLargeTag lt1;
memset(&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);
for (i = 0; i < ntests; ++i) {
tests[i].val = &values[i];
asprintf (&tests[i].name, "AuthorizationData %d", i);
values[i].val = emalloc(values[i].len * sizeof(values[i].val[0]));
}
values[0].val[0].ad_type = 1;
values[0].val[0].ad_data.length = 1;
values[0].val[0].ad_data.data = static_buf512;
return generic_decode_fail(tests, ntests, sizeof(TESTLargeTag),
(generic_decode)decode_TESTLargeTag);
}
values[1].val[0].ad_type = 1;
values[1].val[0].ad_data.length = 126;
values[1].val[0].ad_data.data = static_buf512;
values[2].val[0].ad_type = 1;
values[2].val[0].ad_data.length = 106;
values[2].val[0].ad_data.data = static_buf512;
static int
check_fail_sequence(void)
{
struct test_case tests[] = {
{NULL, 0, "", "empty buffer"},
{NULL, 24,
"\x30\x16\xa0\x03\x02\x01\x01\xa1\x08\x30\x06\xbf\x7f\x03\x02\x01\x01"
"\x02\x01\x01\xa2\x03\x02\x01\x01"
"missing one byte from the end, internal length ok"},
{NULL, 25,
"\x30\x18\xa0\x03\x02\x01\x01\xa1\x08\x30\x06\xbf\x7f\x03\x02\x01\x01"
"\x02\x01\x01\xa2\x03\x02\x01\x01",
"inner length one byte too long"},
{NULL, 24,
"\x30\x17\xa0\x03\x02\x01\x01\xa1\x08\x30\x06\xbf\x7f\x03\x02\x01"
"\x01\x02\x01\x01\xa2\x03\x02\x01\x01",
"correct buffer but missing one to short"},
{NULL, -1, NULL, "overlarger buffer"}
};
int ntests = sizeof(tests) / sizeof(*tests);
values[2].val[1].ad_type = 1;
values[2].val[1].ad_data.length = 1;
values[2].val[1].ad_data.data = static_buf512;
return generic_decode_fail(tests, ntests, sizeof(TESTSeq),
(generic_decode)decode_TESTSeq);
}
values[3].val[0].ad_type = 1;
values[3].val[0].ad_data.length = 107;
values[3].val[0].ad_data.data = static_buf512;
static int
check_fail_choice(void)
{
struct test_case tests[] = {
{NULL, 6,
"\xa1\x02\x02\x01\x01",
"one too short"},
{NULL, 6,
"\xa1\x03\x02\x02\x01",
"one too short inner"},
{NULL, -1, NULL, "overlarger buffer"}
};
int ntests = sizeof(tests) / sizeof(*tests);
values[3].val[1].ad_type = 1;
values[3].val[1].ad_data.length = 2;
values[3].val[1].ad_data.data = static_buf512;
return generic_test (tests, ntests, sizeof(AuthorizationData),
(generic_encode)encode_AuthorizationData,
(generic_length)length_AuthorizationData,
(generic_decode)decode_AuthorizationData,
cmp_AuthorizationData);
return generic_decode_fail(tests, ntests, sizeof(TESTChoice1),
(generic_decode)decode_TESTChoice1);
}
int
@@ -292,7 +688,20 @@ main(int argc, char **argv)
ret += test_principal ();
ret += test_authenticator();
ret += test_AuthorizationData();
ret += test_krb_error();
ret += test_Name();
#if 0
ret += check_heim_integer();
#endif
ret += test_bit_string();
ret += check_tag_length();
ret += test_large_tag();
ret += test_choice();
ret += check_fail_largetag();
ret += check_fail_sequence();
ret += check_fail_choice();
return ret;
}

142
lib/asn1/der.c Normal file
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).
* All rights reserved.
*
@@ -36,145 +36,208 @@
#ifndef __DER_H__
#define __DER_H__
#include <time.h>
typedef enum {
ASN1_C_UNIV = 0,
ASN1_C_APPL = 1,
ASN1_C_CONTEXT = 2 ,
ASN1_C_CONTEXT = 2,
ASN1_C_PRIVATE = 3
} Der_class;
typedef enum {PRIM = 0, CONS = 1} Der_type;
#define MAKE_TAG(CLASS, TYPE, TAG) (((CLASS) << 6) | ((TYPE) << 5) | (TAG))
/* Universal tags */
enum {
UT_Boolean = 1,
UT_Integer = 2,
UT_BitString = 3,
UT_OctetString = 4,
UT_Null = 5,
UT_OID = 6,
UT_Enumerated = 10,
UT_UTF8String = 12,
UT_Sequence = 16,
UT_Set = 17,
UT_PrintableString = 19,
UT_IA5String = 22,
UT_UTCTime = 23,
UT_GeneralizedTime = 24,
UT_VisibleString = 26,
UT_GeneralString = 27
UT_EndOfContent = 0,
UT_Boolean = 1,
UT_Integer = 2,
UT_BitString = 3,
UT_OctetString = 4,
UT_Null = 5,
UT_OID = 6,
UT_Enumerated = 10,
UT_UTF8String = 12,
UT_Sequence = 16,
UT_Set = 17,
UT_PrintableString = 19,
UT_IA5String = 22,
UT_UTCTime = 23,
UT_GeneralizedTime = 24,
UT_VisibleString = 26,
UT_GeneralString = 27,
/* unsupported types */
UT_ObjectDescriptor = 7,
UT_External = 8,
UT_Real = 9,
UT_EmbeddedPDV = 11,
UT_RelativeOID = 13,
UT_NumericString = 18,
UT_TeletexString = 20,
UT_VideotexString = 21,
UT_GraphicString = 25,
UT_UniversalString = 25,
UT_BMPString = 30,
};
#define ASN1_INDEFINITE 0xdce0deed
#ifndef HAVE_TIMEGM
time_t timegm (struct tm *);
#endif
typedef struct asn1_der_time_t {
time_t dt_sec;
unsigned long dt_nsec;
} asn1_der_time_t;
int time2generalizedtime (time_t t, heim_octet_string *s);
typedef struct asn1_ber_time_t {
time_t bt_sec;
unsigned bt_nsec;
int bt_zone;
} asn1_ber_time_t;
int der_get_int (const unsigned char *p, size_t len, int *ret, size_t *size);
int der_get_unsigned (const unsigned char *p, size_t len,
unsigned *ret, size_t *size);
int der_get_integer (const unsigned char *p, size_t len,
int *ret, size_t *size);
int der_get_heim_integer (const unsigned char *p, size_t len,
heim_integer *ret, size_t *size);
int der_get_boolean(const unsigned char *p, size_t len,
int *data, size_t *size);
int der_get_length (const unsigned char *p, size_t len,
size_t *val, size_t *size);
int der_get_boolean (const unsigned char *p, size_t len,
int *data, size_t *size);
int der_get_general_string (const unsigned char *p, size_t len,
heim_general_string *str, size_t *size);
int der_get_utf8string (const unsigned char *p, size_t len,
heim_utf8_string *str, size_t *size);
int der_get_universal_string (const unsigned char *p, size_t len,
heim_universal_string *str, size_t *size);
int der_get_bmp_string (const unsigned char *p, size_t len,
heim_bmp_string *str, size_t *size);
int der_get_printable_string (const unsigned char *p, size_t len,
heim_printable_string *str, size_t *size);
int der_get_ia5_string (const unsigned char *p, size_t len,
heim_ia5_string *str, size_t *size);
int der_get_octet_string (const unsigned char *p, size_t len,
heim_octet_string *data, size_t *size);
int der_get_generalized_time (const unsigned char *p, size_t len,
time_t *data, size_t *size);
int der_get_generalized_time_der (const unsigned char *p, size_t len,
asn1_der_time_t *data, size_t *size);
int der_get_generalized_time_ber (const unsigned char *p, size_t len,
asn1_ber_time_t *data, size_t *size);
int der_get_utctime (const unsigned char *p, size_t len,
time_t *data, size_t *size);
int der_get_oid (const unsigned char *p, size_t len,
heim_oid *data, size_t *size);
int der_get_bit_string (const unsigned char *p, size_t len,
heim_bit_string *data, size_t *size);
int der_get_tag (const unsigned char *p, size_t len,
Der_class *class, Der_type *type,
int *tag, size_t *size);
unsigned int *tag, size_t *size);
int der_match_tag (const unsigned char *p, size_t len,
Der_class class, Der_type type,
int tag, size_t *size);
unsigned int tag, size_t *size);
int der_match_tag_and_length (const unsigned char *p, size_t len,
Der_class class, Der_type type, int tag,
Der_class class, Der_type type, unsigned int tag,
size_t *length_ret, size_t *size);
int decode_boolean (const unsigned char*, size_t, int*, size_t*);
int decode_integer (const unsigned char*, size_t, int*, size_t*);
int decode_unsigned (const unsigned char*, size_t, unsigned*, size_t*);
int decode_enumerated (const unsigned char*, size_t, unsigned*, size_t*);
int decode_general_string (const unsigned char*, size_t,
heim_general_string*, size_t*);
int decode_oid (const unsigned char *p, size_t len,
heim_oid *k, size_t *size);
int decode_octet_string (const unsigned char*, size_t,
heim_octet_string*, size_t*);
int decode_generalized_time (const unsigned char*, size_t, time_t*, size_t*);
int decode_nulltype (const unsigned char*, size_t, size_t*);
int decode_utf8string (const unsigned char*, size_t,
heim_utf8_string*, size_t*);
int der_put_unsigned (unsigned char *p, size_t len, const unsigned *val, size_t*);
int der_put_integer (unsigned char *p, size_t len, const int *val, size_t*);
int der_put_heim_integer (unsigned char *p, size_t len,
const heim_integer *val, size_t*);
int der_put_boolean (unsigned char *p, size_t len, const int *val, size_t*);
int der_put_int (unsigned char *p, size_t len, int val, size_t*);
int der_put_length (unsigned char *p, size_t len, size_t val, size_t*);
int der_put_boolean (unsigned char *p, size_t len, const int *data, size_t*);
int der_put_general_string (unsigned char *p, size_t len,
const heim_general_string *str, size_t*);
int der_put_utf8string (unsigned char *p, size_t len,
const heim_utf8_string *str, size_t*);
int der_put_universal_string (unsigned char *p, size_t len,
const heim_universal_string *str, size_t*);
int der_put_bmp_string (unsigned char *p, size_t len,
const heim_bmp_string *str, size_t*);
int der_put_printable_string (unsigned char *p, size_t len,
const heim_printable_string *str, size_t*);
int der_put_ia5_string (unsigned char *p, size_t len,
const heim_ia5_string *str, size_t*);
int der_put_octet_string (unsigned char *p, size_t len,
const heim_octet_string *data, size_t*);
int der_put_generalized_time (unsigned char *p, size_t len,
const time_t *data, size_t *size);
int der_put_utctime (unsigned char *p, size_t len,
const time_t *data, size_t *size);
int der_put_oid (unsigned char *p, size_t len,
const heim_oid *data, size_t *size);
int der_put_bit_string (unsigned char *p, size_t len,
const heim_bit_string *data, size_t *size);
int der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
int tag, size_t*);
unsigned int tag, size_t*);
int der_put_length_and_tag (unsigned char*, size_t, size_t,
Der_class, Der_type, int, size_t*);
int encode_boolean (unsigned char *p, size_t len,
const int *data, size_t*);
int encode_integer (unsigned char *p, size_t len,
const int *data, size_t*);
int encode_unsigned (unsigned char *p, size_t len,
const unsigned *data, size_t*);
int encode_enumerated (unsigned char *p, size_t len,
const unsigned *data, size_t*);
int encode_general_string (unsigned char *p, size_t len,
const heim_general_string *data, size_t*);
int encode_octet_string (unsigned char *p, size_t len,
const heim_octet_string *k, size_t*);
int encode_oid (unsigned char *p, size_t len,
const heim_oid *k, size_t*);
int encode_generalized_time (unsigned char *p, size_t len,
const time_t *t, size_t*);
int encode_nulltype (unsigned char*, size_t, size_t*);
int encode_utf8string (unsigned char*, size_t,
const heim_utf8_string*, size_t*);
Der_class, Der_type, unsigned int, size_t*);
void free_integer (int *num);
void free_heim_integer (heim_integer *num);
void free_octet_string (heim_octet_string *k);
void free_general_string (heim_general_string *str);
void free_octet_string (heim_octet_string *k);
void free_oid (heim_oid *k);
void free_bit_string (heim_bit_string *k);
void free_generalized_time (time_t *t);
void free_utctime (time_t *t);
void free_utf8string (heim_utf8_string*);
void free_printable_string (heim_printable_string*);
void free_ia5_string (heim_ia5_string*);
void free_universal_string (heim_universal_string*);
void free_bmp_string (heim_bmp_string*);
size_t length_len (size_t len);
size_t length_boolean (const int *data);
size_t length_integer (const int *data);
size_t length_heim_integer (const heim_integer *data);
size_t length_unsigned (const unsigned *data);
size_t length_enumerated (const unsigned *data);
size_t length_general_string (const heim_general_string *data);
size_t length_octet_string (const heim_octet_string *k);
size_t length_oid (const heim_oid *k);
size_t length_bit_string (const heim_bit_string *k);
size_t length_generalized_time (const time_t *t);
size_t length_nulltype (void);
size_t length_utctime (const time_t *t);
size_t length_utf8string (const heim_utf8_string*);
size_t length_printable_string (const heim_printable_string*);
size_t length_ia5_string (const heim_ia5_string*);
size_t length_bmp_string (const heim_bmp_string*);
size_t length_universal_string (const heim_universal_string*);
size_t length_boolean (const int*);
int copy_heim_integer (const heim_integer *, heim_integer *);
int copy_general_string (const heim_general_string *, heim_general_string *);
int copy_octet_string (const heim_octet_string *, heim_octet_string *);
int copy_oid (const heim_oid *from, heim_oid *to);
int copy_nulltype (void *, void *);
int copy_bit_string (const heim_bit_string *from, heim_bit_string *to);
int copy_utf8string (const heim_utf8_string*, heim_utf8_string*);
int copy_printable_string (const heim_printable_string*,heim_printable_string*);
int copy_ia5_string (const heim_ia5_string*,heim_ia5_string*);
int copy_universal_string(const heim_universal_string*,heim_universal_string*);
int copy_bmp_string (const heim_bmp_string*,heim_bmp_string*);
int heim_oid_cmp(const heim_oid *, const heim_oid *);
int heim_octet_string_cmp(const heim_octet_string *,const heim_octet_string *);
int heim_bit_string_cmp(const heim_bit_string *, const heim_bit_string *);
int heim_integer_cmp(const heim_integer *, const heim_integer *);
int heim_bmp_string_cmp(const heim_bmp_string *, const heim_bmp_string *);
int heim_universal_string_cmp(const heim_universal_string *,
const heim_universal_string *);
int fix_dce(size_t reallen, size_t *len);
int der_parse_oid(const char *, heim_oid *);
int _heim_fix_dce(size_t reallen, size_t *len);
int _heim_der_set_sort(const void *, const void *);
int _heim_time2generalizedtime (time_t, heim_octet_string *, int);
const char * der_get_class_name(unsigned);
int der_get_class_num(const char *);
const char * der_get_type_name(unsigned);
int der_get_type_num(const char *);
const char * der_get_tag_name(unsigned);
int der_get_tag_num(const char *);
#endif /* __DER_H__ */

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).
* All rights reserved.
*
@@ -33,8 +33,6 @@
#include "der_locl.h"
RCSID("$Id$");
int
heim_oid_cmp(const heim_oid *p, const heim_oid *q)
{
@@ -52,3 +50,48 @@ heim_octet_string_cmp(const heim_octet_string *p, const heim_octet_string *q)
return p->length - q->length;
return memcmp(p->data, q->data, p->length);
}
int
heim_bit_string_cmp(const heim_bit_string *p, const heim_bit_string *q)
{
int i, r1, r2;
if (p->length != q->length)
return p->length - q->length;
i = memcmp(p->data, q->data, p->length / 8);
if (i)
return i;
i = p->length / 8;
r1 = ((unsigned char *)p->data)[i];
r2 = ((unsigned char *)q->data)[i];
i = 8 - p->length % 8;
r1 = r1 >> i;
r2 = r2 >> i;
return r1 - r2;
}
int
heim_integer_cmp(const heim_integer *p, const heim_integer *q)
{
if (p->length != q->length)
return p->length - q->length;
if (p->negative != q->negative)
return p->negative - q->negative;
return memcmp(p->data, q->data, p->length);
}
int
heim_bmp_string_cmp(const heim_bmp_string *p, const heim_bmp_string *q)
{
if (p->length != q->length)
return p->length - q->length;
return memcmp(p->data, q->data, q->length * sizeof(q->data[0]));
}
int
heim_universal_string_cmp(const heim_universal_string *p,
const heim_universal_string *q)
{
if (p->length != q->length)
return p->length - q->length;
return memcmp(p->data, q->data, q->length * sizeof(q->data[0]));
}

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).
* All rights reserved.
*
@@ -44,6 +44,49 @@ copy_general_string (const heim_general_string *from, heim_general_string *to)
return 0;
}
int
copy_utf8string (const heim_utf8_string *from, heim_utf8_string *to)
{
return copy_general_string(from, to);
}
int
copy_printable_string (const heim_printable_string *from,
heim_printable_string *to)
{
return copy_general_string(from, to);
}
int
copy_ia5_string (const heim_printable_string *from,
heim_printable_string *to)
{
return copy_general_string(from, to);
}
int
copy_bmp_string (const heim_bmp_string *from, heim_bmp_string *to)
{
to->length = from->length;
to->data = malloc(to->length * sizeof(to->data[0]));
if(to->length != 0 && to->data == NULL)
return ENOMEM;
memcpy(to->data, from->data, to->length * sizeof(to->data[0]));
return 0;
}
int
copy_universal_string (const heim_universal_string *from,
heim_universal_string *to)
{
to->length = from->length;
to->data = malloc(to->length * sizeof(to->data[0]));
if(to->length != 0 && to->data == NULL)
return ENOMEM;
memcpy(to->data, from->data, to->length * sizeof(to->data[0]));
return 0;
}
int
copy_octet_string (const heim_octet_string *from, heim_octet_string *to)
{
@@ -55,6 +98,17 @@ copy_octet_string (const heim_octet_string *from, heim_octet_string *to)
return 0;
}
int
copy_heim_integer (const heim_integer *from, heim_integer *to)
{
to->length = from->length;
to->data = malloc(to->length);
if(to->length != 0 && to->data == NULL)
return ENOMEM;
memcpy(to->data, from->data, to->length);
return 0;
}
int
copy_oid (const heim_oid *from, heim_oid *to)
{
@@ -66,3 +120,17 @@ copy_oid (const heim_oid *from, heim_oid *to)
to->length * sizeof(*to->components));
return 0;
}
int
copy_bit_string (const heim_bit_string *from, heim_bit_string *to)
{
size_t len;
len = (from->length + 7) / 8;
to->length = from->length;
to->data = malloc(len);
if(len != 0 && to->data == NULL)
return ENOMEM;
memcpy(to->data, from->data, len);
return 0;
}

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).
* All rights reserved.
*
@@ -42,11 +42,56 @@ free_general_string (heim_general_string *str)
*str = NULL;
}
void
free_utf8string (heim_utf8_string *str)
{
free(*str);
*str = NULL;
}
void
free_printable_string (heim_printable_string *str)
{
free(*str);
*str = NULL;
}
void
free_ia5_string (heim_ia5_string *str)
{
free_general_string(str);
}
void
free_bmp_string (heim_bmp_string *k)
{
free(k->data);
k->data = NULL;
k->length = 0;
}
void
free_universal_string (heim_universal_string *k)
{
free(k->data);
k->data = NULL;
k->length = 0;
}
void
free_octet_string (heim_octet_string *k)
{
free(k->data);
k->data = NULL;
k->length = 0;
}
void
free_heim_integer (heim_integer *k)
{
free(k->data);
k->data = NULL;
k->length = 0;
}
void
@@ -54,4 +99,13 @@ free_oid (heim_oid *k)
{
free(k->components);
k->components = NULL;
k->length = 0;
}
void
free_bit_string (heim_bit_string *k)
{
free(k->data);
k->data = NULL;
k->length = 0;
}

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).
* All rights reserved.
*
@@ -45,13 +45,18 @@ RCSID("$Id$");
* Either 0 or an error code is returned.
*/
static int
int
der_get_unsigned (const unsigned char *p, size_t len,
unsigned *ret, size_t *size)
{
unsigned val = 0;
size_t oldlen = len;
if (len == sizeof(unsigned) + 1 && p[0] == 0)
;
else if (len > sizeof(unsigned))
return ASN1_OVERRUN;
while (len--)
val = val * 256 + *p++;
*ret = val;
@@ -60,12 +65,15 @@ der_get_unsigned (const unsigned char *p, size_t len,
}
int
der_get_int (const unsigned char *p, size_t len,
int *ret, size_t *size)
der_get_integer (const unsigned char *p, size_t len,
int *ret, size_t *size)
{
int val = 0;
size_t oldlen = len;
if (len > sizeof(int))
return ASN1_OVERRUN;
if (len > 0) {
val = (signed char)*p++;
while (--len)
@@ -76,19 +84,6 @@ der_get_int (const unsigned char *p, size_t len,
return 0;
}
int
der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size)
{
if(len < 1)
return ASN1_OVERRUN;
if(*p != 0)
*data = 1;
else
*data = 0;
*size = 1;
return 0;
}
int
der_get_length (const unsigned char *p, size_t len,
size_t *val, size_t *size)
@@ -123,12 +118,28 @@ der_get_length (const unsigned char *p, size_t len,
return 0;
}
int
der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size)
{
if(len < 1)
return ASN1_OVERRUN;
if(*p != 0)
*data = 1;
else
*data = 0;
*size = 1;
return 0;
}
int
der_get_general_string (const unsigned char *p, size_t len,
heim_general_string *str, size_t *size)
{
char *s;
if (len > SIZE_T_MAX - 1)
return ASN1_BAD_LENGTH;
s = malloc (len + 1);
if (s == NULL)
return ENOMEM;
@@ -139,6 +150,70 @@ der_get_general_string (const unsigned char *p, size_t len,
return 0;
}
int
der_get_utf8string (const unsigned char *p, size_t len,
heim_utf8_string *str, size_t *size)
{
return der_get_general_string(p, len, str, size);
}
int
der_get_printable_string (const unsigned char *p, size_t len,
heim_printable_string *str, size_t *size)
{
return der_get_general_string(p, len, str, size);
}
int
der_get_ia5_string (const unsigned char *p, size_t len,
heim_ia5_string *str, size_t *size)
{
return der_get_general_string(p, len, str, size);
}
int
der_get_bmp_string (const unsigned char *p, size_t len,
heim_bmp_string *data, size_t *size)
{
size_t i;
if (len & 1)
return ASN1_BAD_FORMAT;
data->length = len / 2;
data->data = malloc(data->length * sizeof(data->data[0]));
if (data->data == NULL && data->length != 0)
return ENOMEM;
for (i = 0; i < data->length; i++) {
data->data[i] = (p[0] << 8) | p[1];
p += 2;
}
if (size) *size = len;
return 0;
}
int
der_get_universal_string (const unsigned char *p, size_t len,
heim_universal_string *data, size_t *size)
{
size_t i;
if (len & 3)
return ASN1_BAD_FORMAT;
data->length = len / 4;
data->data = malloc(data->length * sizeof(data->data[0]));
if (data->data == NULL && data->length != 0)
return ENOMEM;
for (i = 0; i < data->length; i++) {
data->data[i] = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
p += 4;
}
if (size) *size = len;
return 0;
}
int
der_get_octet_string (const unsigned char *p, size_t len,
heim_octet_string *data, size_t *size)
@@ -152,6 +227,108 @@ der_get_octet_string (const unsigned char *p, size_t len,
return 0;
}
int
der_get_heim_integer (const unsigned char *p, size_t len,
heim_integer *data, size_t *size)
{
data->length = 0;
data->negative = 0;
data->data = NULL;
if (len == 0) {
if (size)
*size = 0;
return 0;
}
if (p[0] & 0x80) {
data->negative = 1;
return ASN1_OVERRUN;
} else {
data->negative = 0;
data->length = len;
if (p[0] == 0 && data->length != 1) {
p++;
data->length--;
}
data->data = malloc(data->length);
if (data->data == NULL) {
data->length = 0;
return ENOMEM;
}
memcpy(data->data, p, data->length);
}
if (size)
*size = len;
return 0;
}
static int
generalizedtime2time (const char *s, time_t *t)
{
struct tm tm;
memset(&tm, 0, sizeof(tm));
if (sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
&tm.tm_min, &tm.tm_sec) != 6) {
if (sscanf (s, "%02d%02d%02d%02d%02d%02dZ",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
&tm.tm_min, &tm.tm_sec) != 6)
return ASN1_BAD_TIMEFORMAT;
if (tm.tm_year < 50)
tm.tm_year += 2000;
else
tm.tm_year += 1900;
}
tm.tm_year -= 1900;
tm.tm_mon -= 1;
*t = timegm (&tm);
return 0;
}
static int
der_get_time (const unsigned char *p, size_t len,
time_t *data, size_t *size)
{
heim_octet_string k;
char *times;
size_t ret = 0;
size_t l;
int e;
e = der_get_octet_string (p, len, &k, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
times = realloc(k.data, k.length + 1);
if (times == NULL){
free(k.data);
return ENOMEM;
}
times[k.length] = 0;
e = generalizedtime2time(times, data);
free (times);
if(size) *size = ret;
return e;
}
int
der_get_generalized_time (const unsigned char *p, size_t len,
time_t *data, size_t *size)
{
return der_get_time(p, len, data, size);
}
int
der_get_utctime (const unsigned char *p, size_t len,
time_t *data, size_t *size)
{
return der_get_time(p, len, data, size);
}
int
der_get_oid (const unsigned char *p, size_t len,
heim_oid *data, size_t *size)
@@ -162,6 +339,9 @@ der_get_oid (const unsigned char *p, size_t len,
if (len < 1)
return ASN1_OVERRUN;
if (len > SIZE_T_MAX - 1)
return ASN1_BAD_LENGTH;
data->components = malloc((len + 1) * sizeof(*data->components));
if (data->components == NULL)
return ENOMEM;
@@ -170,15 +350,21 @@ der_get_oid (const unsigned char *p, size_t len,
--len;
++p;
for (n = 2; len > 0; ++n) {
unsigned u = 0;
unsigned u = 0, u1;
do {
--len;
u = u * 128 + (*p++ % 128);
u1 = u * 128 + (*p++ % 128);
/* check that we don't overflow the element */
if (u1 < u) {
free_oid(data);
return ASN1_OVERRUN;
}
u = u1;
} while (len > 0 && p[-1] & 0x80);
data->components[n] = u;
}
if (len > 0 && p[-1] & 0x80) {
if (n > 2 && p[-1] & 0x80) {
free_oid (data);
return ASN1_OVERRUN;
}
@@ -191,21 +377,39 @@ der_get_oid (const unsigned char *p, size_t len,
int
der_get_tag (const unsigned char *p, size_t len,
Der_class *class, Der_type *type,
int *tag, size_t *size)
unsigned int *tag, size_t *size)
{
size_t ret = 0;
if (len < 1)
return ASN1_OVERRUN;
*class = (Der_class)(((*p) >> 6) & 0x03);
*type = (Der_type)(((*p) >> 5) & 0x01);
*tag = (*p) & 0x1F;
if(size) *size = 1;
*tag = (*p) & 0x1f;
p++; len--; ret++;
if(*tag == 0x1f) {
unsigned int continuation;
unsigned int tag1;
*tag = 0;
do {
if(len < 1)
return ASN1_OVERRUN;
continuation = *p & 128;
tag1 = *tag * 128 + (*p % 128);
/* check that we don't overflow the tag */
if (tag1 < *tag)
return ASN1_OVERFLOW;
*tag = tag1;
p++; len--; ret++;
} while(continuation);
}
if(size) *size = ret;
return 0;
}
int
der_match_tag (const unsigned char *p, size_t len,
Der_class class, Der_type type,
int tag, size_t *size)
unsigned int tag, size_t *size)
{
size_t l;
Der_class thisclass;
@@ -227,7 +431,7 @@ der_match_tag (const unsigned char *p, size_t len,
int
der_match_tag_and_length (const unsigned char *p, size_t len,
Der_class class, Der_type type, int tag,
Der_class class, Der_type type, unsigned int tag,
size_t *length_ret, size_t *size)
{
size_t l, ret = 0;
@@ -238,7 +442,6 @@ der_match_tag_and_length (const unsigned char *p, size_t len,
p += l;
len -= l;
ret += l;
e = der_get_length (p, len, length_ret, &l);
if (e) return e;
p += l;
@@ -248,281 +451,21 @@ der_match_tag_and_length (const unsigned char *p, size_t len,
return 0;
}
int
decode_boolean (const unsigned char *p, size_t len,
int *num, size_t *size)
{
size_t ret = 0;
size_t l, reallen;
int e;
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_Boolean, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
e = der_get_length (p, len, &reallen, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if (reallen > len)
return ASN1_OVERRUN;
e = der_get_boolean (p, reallen, num, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if(size) *size = ret;
return 0;
}
/*
* Old versions of DCE was based on a very early beta of the MIT code,
* which used MAVROS for ASN.1 encoding. MAVROS had the interesting
* feature that it encoded data in the forward direction, which has
* it's problems, since you have no idea how long the data will be
* until after you're done. MAVROS solved this by reserving one byte
* for length, and later, if the actual length was longer, it reverted
* to indefinite, BER style, lengths. The version of MAVROS used by
* the DCE people could apparently generate correct X.509 DER encodings, and
* did this by making space for the length after encoding, but
* unfortunately this feature wasn't used with Kerberos.
*/
int
decode_integer (const unsigned char *p, size_t len,
int *num, size_t *size)
{
size_t ret = 0;
size_t l, reallen;
int e;
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_Integer, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
e = der_get_length (p, len, &reallen, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if (reallen > len)
return ASN1_OVERRUN;
e = der_get_int (p, reallen, num, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if(size) *size = ret;
return 0;
}
int
decode_unsigned (const unsigned char *p, size_t len,
unsigned *num, size_t *size)
{
size_t ret = 0;
size_t l, reallen;
int e;
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_Integer, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
e = der_get_length (p, len, &reallen, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if (reallen > len)
return ASN1_OVERRUN;
e = der_get_unsigned (p, reallen, num, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if(size) *size = ret;
return 0;
}
int
decode_enumerated (const unsigned char *p, size_t len,
unsigned *num, size_t *size)
{
size_t ret = 0;
size_t l, reallen;
int e;
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_Enumerated, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
e = der_get_length (p, len, &reallen, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if (reallen > len)
return ASN1_OVERRUN;
e = der_get_int (p, reallen, num, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if(size) *size = ret;
return 0;
}
int
decode_general_string (const unsigned char *p, size_t len,
heim_general_string *str, size_t *size)
{
size_t ret = 0;
size_t l, reallen;
int e;
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_GeneralString, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
e = der_get_length (p, len, &reallen, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if (len < reallen)
return ASN1_OVERRUN;
e = der_get_general_string (p, reallen, str, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if(size) *size = ret;
return 0;
}
int
decode_octet_string (const unsigned char *p, size_t len,
heim_octet_string *k, size_t *size)
{
size_t ret = 0;
size_t l, reallen;
int e;
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_OctetString, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
e = der_get_length (p, len, &reallen, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if (len < reallen)
return ASN1_OVERRUN;
e = der_get_octet_string (p, reallen, k, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if(size) *size = ret;
return 0;
}
int
decode_oid (const unsigned char *p, size_t len,
heim_oid *k, size_t *size)
{
size_t ret = 0;
size_t l, reallen;
int e;
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_OID, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
e = der_get_length (p, len, &reallen, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if (len < reallen)
return ASN1_OVERRUN;
e = der_get_oid (p, reallen, k, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if(size) *size = ret;
return 0;
}
static void
generalizedtime2time (const char *s, time_t *t)
{
struct tm tm;
memset(&tm, 0, sizeof(tm));
sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
&tm.tm_min, &tm.tm_sec);
tm.tm_year -= 1900;
tm.tm_mon -= 1;
*t = timegm (&tm);
}
int
decode_generalized_time (const unsigned char *p, size_t len,
time_t *t, size_t *size)
{
heim_octet_string k;
char *times;
size_t ret = 0;
size_t l, reallen;
int e;
e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_GeneralizedTime, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
e = der_get_length (p, len, &reallen, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if (len < reallen)
return ASN1_OVERRUN;
e = der_get_octet_string (p, reallen, &k, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
times = realloc(k.data, k.length + 1);
if (times == NULL){
free(k.data);
return ENOMEM;
}
times[k.length] = 0;
generalizedtime2time (times, t);
free (times);
if(size) *size = ret;
return 0;
}
int
fix_dce(size_t reallen, size_t *len)
_heim_fix_dce(size_t reallen, size_t *len)
{
if(reallen == ASN1_INDEFINITE)
return 1;
@@ -531,3 +474,25 @@ fix_dce(size_t reallen, size_t *len)
*len = reallen;
return 0;
}
int
der_get_bit_string (const unsigned char *p, size_t len,
heim_bit_string *data, size_t *size)
{
if (len < 1)
return ASN1_OVERRUN;
if (p[0] > 7)
return ASN1_BAD_FORMAT;
if (len - 1 == 0 && p[0] != 0)
return ASN1_BAD_FORMAT;
if (len - 1 > SIZE_T_MAX / 8)
return ASN1_OVERRUN;
data->length = (len - 1) * 8;
data->data = malloc(len - 1);
if (data->data == NULL && (len - 1) != 0)
return ENOMEM;
memcpy (data->data, p + 1, len - 1);
data->length -= p[0];
if(size) *size = len;
return 0;
}

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).
* All rights reserved.
*
@@ -39,11 +39,17 @@ size_t
_heim_len_unsigned (unsigned val)
{
size_t ret = 0;
int last_val_gt_128;
do {
++ret;
last_val_gt_128 = (val >= 128);
val /= 256;
} while (val);
if(last_val_gt_128)
ret++;
return ret;
}
@@ -83,12 +89,10 @@ len_oid (const heim_oid *oid)
for (n = 2; n < oid->length; ++n) {
unsigned u = oid->components[n];
++ret;
u /= 128;
while (u > 0) {
do {
++ret;
u /= 128;
}
} while(u > 0);
}
return ret;
}
@@ -98,68 +102,91 @@ length_len (size_t len)
{
if (len < 128)
return 1;
else
return _heim_len_unsigned (len) + 1;
}
size_t
length_boolean (const int *data)
{
return 1 + length_len(1) + 1;
else {
int ret = 0;
do {
++ret;
len /= 256;
} while (len);
return ret + 1;
}
}
size_t
length_integer (const int *data)
{
size_t len = _heim_len_int (*data);
return 1 + length_len(len) + len;
return _heim_len_int (*data);
}
size_t
length_unsigned (const unsigned *data)
{
unsigned val = *data;
size_t len = 0;
while (val > 255) {
++len;
val /= 256;
}
len++;
if (val >= 128)
len++;
return 1 + length_len(len) + len;
return _heim_len_unsigned(*data);
}
size_t
length_enumerated (const unsigned *data)
{
size_t len = _heim_len_int (*data);
return 1 + length_len(len) + len;
return _heim_len_int (*data);
}
size_t
length_general_string (const heim_general_string *data)
{
char *str = *data;
size_t len = strlen(str);
return 1 + length_len(len) + len;
return strlen(*data);
}
size_t
length_utf8string (const heim_utf8_string *data)
{
return strlen(*data);
}
size_t
length_printable_string (const heim_printable_string *data)
{
return strlen(*data);
}
size_t
length_ia5_string (const heim_ia5_string *data)
{
return strlen(*data);
}
size_t
length_bmp_string (const heim_bmp_string *data)
{
return data->length * 2;
}
size_t
length_universal_string (const heim_universal_string *data)
{
return data->length * 4;
}
size_t
length_octet_string (const heim_octet_string *k)
{
return 1 + length_len(k->length) + k->length;
return k->length;
}
size_t
length_heim_integer (const heim_integer *k)
{
if (k->length == 0)
return 1;
if (k->negative)
return k->length + ((((unsigned char *)k->data)[0] & 0x80) ? 0 : 1);
else
return k->length + ((((unsigned char *)k->data)[0] & 0x80) ? 1 : 0);
}
size_t
length_oid (const heim_oid *k)
{
size_t len = len_oid (k);
return 1 + length_len(len) + len;
return len_oid (k);
}
size_t
@@ -168,8 +195,32 @@ length_generalized_time (const time_t *t)
heim_octet_string k;
size_t ret;
time2generalizedtime (*t, &k);
ret = 1 + length_len(k.length) + k.length;
free (k.data);
_heim_time2generalizedtime (*t, &k, 1);
ret = k.length;
free(k.data);
return ret;
}
size_t
length_utctime (const time_t *t)
{
heim_octet_string k;
size_t ret;
_heim_time2generalizedtime (*t, &k, 0);
ret = k.length;
free(k.data);
return ret;
}
size_t
length_boolean (const int *k)
{
return 1;
}
size_t
length_bit_string (const heim_bit_string *k)
{
return (k->length + 7) / 8 + 1;
}

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

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).
* All rights reserved.
*
@@ -43,10 +43,11 @@ RCSID("$Id$");
* The return value is 0 or an error.
*/
static int
der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size)
int
der_put_unsigned (unsigned char *p, size_t len, const unsigned *v, size_t *size)
{
unsigned char *base = p;
unsigned val = *v;
if (val) {
while (len > 0 && val) {
@@ -57,6 +58,11 @@ der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size)
if (val != 0)
return ASN1_OVERFLOW;
else {
if(p[1] >= 128) {
if(len < 1)
return ASN1_OVERFLOW;
*p-- = 0;
}
*size = base - p;
return 0;
}
@@ -70,9 +76,10 @@ der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size)
}
int
der_put_int (unsigned char *p, size_t len, int val, size_t *size)
der_put_integer (unsigned char *p, size_t len, const int *v, size_t *size)
{
unsigned char *base = p;
int val = *v;
if(val >= 0) {
do {
@@ -114,22 +121,26 @@ der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
{
if (len < 1)
return ASN1_OVERFLOW;
if (val < 128) {
*p = val;
*size = 1;
return 0;
} else {
size_t l;
int e;
size_t l = 0;
e = der_put_unsigned (p, len - 1, val, &l);
if (e)
return e;
p -= l;
while(val > 0) {
if(len < 2)
return ASN1_OVERFLOW;
*p-- = val % 256;
val /= 256;
len--;
l++;
}
*p = 0x80 | l;
*size = l + 1;
return 0;
if(size)
*size = l + 1;
}
return 0;
}
int
@@ -160,6 +171,65 @@ der_put_general_string (unsigned char *p, size_t len,
return 0;
}
int
der_put_utf8string (unsigned char *p, size_t len,
const heim_utf8_string *str, size_t *size)
{
return der_put_general_string(p, len, str, size);
}
int
der_put_printable_string (unsigned char *p, size_t len,
const heim_printable_string *str, size_t *size)
{
return der_put_general_string(p, len, str, size);
}
int
der_put_ia5_string (unsigned char *p, size_t len,
const heim_ia5_string *str, size_t *size)
{
return der_put_general_string(p, len, str, size);
}
int
der_put_bmp_string (unsigned char *p, size_t len,
const heim_bmp_string *data, size_t *size)
{
size_t i;
if (len / 2 < data->length)
return ASN1_OVERFLOW;
p -= data->length * 2;
len -= data->length * 2;
for (i = 0; i < data->length; i++) {
p[1] = (data->data[i] >> 8) & 0xff;
p[2] = data->data[i] & 0xff;
p += 2;
}
if (size) *size = data->length * 2;
return 0;
}
int
der_put_universal_string (unsigned char *p, size_t len,
const heim_universal_string *data, size_t *size)
{
size_t i;
if (len / 4 < data->length)
return ASN1_OVERFLOW;
p -= data->length * 4;
len -= data->length * 4;
for (i = 0; i < data->length; i++) {
p[1] = (data->data[i] >> 24) & 0xff;
p[2] = (data->data[i] >> 16) & 0xff;
p[3] = (data->data[i] >> 8) & 0xff;
p[4] = data->data[i] & 0xff;
p += 4;
}
if (size) *size = data->length * 4;
return 0;
}
int
der_put_octet_string (unsigned char *p, size_t len,
const heim_octet_string *data, size_t *size)
@@ -173,6 +243,98 @@ der_put_octet_string (unsigned char *p, size_t len,
return 0;
}
int
der_put_heim_integer (unsigned char *p, size_t len,
const heim_integer *data, size_t *size)
{
unsigned char *buf = data->data;
int hibitset = 0;
if (data->length == 0) {
if (len < 1)
return ASN1_OVERFLOW;
*p-- = 0;
if (size)
*size = 1;
return 0;
}
if (len < data->length)
return ASN1_OVERFLOW;
len -= data->length;
if (data->negative) {
int i, carry;
for (i = data->length - 1, carry = 1; i >= 0; i--) {
*p = buf[i] ^ 0xff;
if (carry)
carry = !++*p;
p--;
}
if (p[1] < 128) {
if (len < 1)
return ASN1_OVERFLOW;
*p-- = 0xff;
len--;
hibitset = 1;
}
} else {
p -= data->length;
memcpy(p + 1, buf, data->length);
if (p[1] >= 128) {
if (len < 1)
return ASN1_OVERFLOW;
p[0] = 0;
len--;
hibitset = 1;
}
}
if (size)
*size = data->length + hibitset;
return 0;
}
int
der_put_generalized_time (unsigned char *p, size_t len,
const time_t *data, size_t *size)
{
heim_octet_string k;
size_t l;
int e;
e = _heim_time2generalizedtime (*data, &k, 1);
if (e)
return e;
e = der_put_octet_string(p, len, &k, &l);
free(k.data);
if(e)
return e;
if(size)
*size = l;
return 0;
}
int
der_put_utctime (unsigned char *p, size_t len,
const time_t *data, size_t *size)
{
heim_octet_string k;
size_t l;
int e;
e = _heim_time2generalizedtime (*data, &k, 0);
if (e)
return e;
e = der_put_octet_string(p, len, &k, &l);
free(k.data);
if(e)
return e;
if(size)
*size = l;
return 0;
}
int
der_put_oid (unsigned char *p, size_t len,
const heim_oid *data, size_t *size)
@@ -205,18 +367,39 @@ der_put_oid (unsigned char *p, size_t len,
int
der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
int tag, size_t *size)
unsigned int tag, size_t *size)
{
if (len < 1)
return ASN1_OVERFLOW;
*p = (class << 6) | (type << 5) | tag; /* XXX */
*size = 1;
if (tag <= 30) {
if (len < 1)
return ASN1_OVERFLOW;
*p = MAKE_TAG(class, type, tag);
*size = 1;
} else {
size_t ret = 0;
unsigned int continuation = 0;
do {
if (len < 1)
return ASN1_OVERFLOW;
*p-- = tag % 128 | continuation;
len--;
ret++;
tag /= 128;
continuation = 0x80;
} while(tag > 0);
if (len < 1)
return ASN1_OVERFLOW;
*p-- = MAKE_TAG(class, type, 0x1f);
ret++;
*size = ret;
}
return 0;
}
int
der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
Der_class class, Der_type type, int tag, size_t *size)
Der_class class, Der_type type,
unsigned int tag, size_t *size)
{
size_t ret = 0;
size_t l;
@@ -239,229 +422,55 @@ der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
}
int
encode_boolean (unsigned char *p, size_t len, const int *data,
size_t *size)
{
size_t ret = 0;
size_t l;
int e;
e = der_put_boolean (p, len, data, &l);
if(e)
return e;
p -= l;
len -= l;
ret += l;
e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_Boolean, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
*size = ret;
return 0;
}
int
encode_integer (unsigned char *p, size_t len, const int *data, size_t *size)
{
int num = *data;
size_t ret = 0;
size_t l;
int e;
e = der_put_int (p, len, num, &l);
if(e)
return e;
p -= l;
len -= l;
ret += l;
e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_Integer, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
*size = ret;
return 0;
}
int
encode_unsigned (unsigned char *p, size_t len, const unsigned *data,
size_t *size)
{
unsigned num = *data;
size_t ret = 0;
size_t l;
int e;
e = der_put_unsigned (p, len, num, &l);
if(e)
return e;
p -= l;
len -= l;
ret += l;
/* if first octet has msb set, we need to pad with a zero byte */
if(p[1] >= 128) {
if(len == 0)
return ASN1_OVERFLOW;
*p-- = 0;
len--;
ret++;
l++;
}
e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_Integer, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
*size = ret;
return 0;
}
int
encode_enumerated (unsigned char *p, size_t len, const unsigned *data,
size_t *size)
{
unsigned num = *data;
size_t ret = 0;
size_t l;
int e;
e = der_put_int (p, len, num, &l);
if(e)
return e;
p -= l;
len -= l;
ret += l;
e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_Enumerated, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
*size = ret;
return 0;
}
int
encode_general_string (unsigned char *p, size_t len,
const heim_general_string *data, size_t *size)
{
size_t ret = 0;
size_t l;
int e;
e = der_put_general_string (p, len, data, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_GeneralString, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
*size = ret;
return 0;
}
int
encode_octet_string (unsigned char *p, size_t len,
const heim_octet_string *k, size_t *size)
{
size_t ret = 0;
size_t l;
int e;
e = der_put_octet_string (p, len, k, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_OctetString, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
*size = ret;
return 0;
}
int
encode_oid(unsigned char *p, size_t len,
const heim_oid *k, size_t *size)
{
size_t ret = 0;
size_t l;
int e;
e = der_put_oid (p, len, k, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_OID, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
*size = ret;
return 0;
}
int
time2generalizedtime (time_t t, heim_octet_string *s)
_heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep)
{
struct tm *tm;
size_t len;
len = 15;
const size_t len = gtimep ? 15 : 13;
s->data = malloc(len + 1);
if (s->data == NULL)
return ENOMEM;
s->length = len;
tm = gmtime (&t);
snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
if (gtimep)
snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
else
snprintf (s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ",
tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
return 0;
}
int
encode_generalized_time (unsigned char *p, size_t len,
const time_t *t, size_t *size)
der_put_bit_string (unsigned char *p, size_t len,
const heim_bit_string *data, size_t *size)
{
size_t ret = 0;
size_t l;
heim_octet_string k;
int e;
e = time2generalizedtime (*t, &k);
if (e)
return e;
e = der_put_octet_string (p, len, &k, &l);
free (k.data);
if (e)
return e;
p -= l;
len -= l;
ret += l;
e = der_put_length_and_tag (p, len, k.length, ASN1_C_UNIV, PRIM,
UT_GeneralizedTime, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
*size = ret;
size_t data_size = (data->length + 7) / 8;
if (len < data_size + 1)
return ASN1_OVERFLOW;
p -= data_size + 1;
len -= data_size + 1;
memcpy (p+2, data->data, data_size);
if (data->length && (data->length % 8) != 0)
p[1] = 8 - (data->length % 8);
else
p[1] = 0;
*size = data_size + 1;
return 0;
}
int
_heim_der_set_sort(const void *a1, const void *a2)
{
const struct heim_octet_string *s1 = a1, *s2 = a2;
int ret;
ret = memcmp(s1->data, s2->data,
s1->length < s2->length ? s1->length : s2->length);
if(ret)
return ret;
return s1->length - s2->length;
}

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).
* All rights reserved.
*
@@ -103,7 +103,7 @@ int
copy_heim_any(const heim_any *from, heim_any *to)
{
to->data = malloc(from->length);
if (to->data == NULL)
if (to->data == NULL && from->length != 0)
return ENOMEM;
memcpy(to->data, from->data, from->length);
to->length = from->length;
@@ -124,7 +124,7 @@ decode_heim_any_set(const unsigned char *p, size_t len,
{
memset(data, 0, sizeof(*data));
data->data = malloc(len);
if (data->data == NULL)
if (data->data == NULL && len != 0)
return ENOMEM;
data->length = len;
memcpy(data->data, p, len);
@@ -149,3 +149,11 @@ copy_heim_any_set(const heim_any_set *from, heim_any_set *to)
{
return copy_heim_any(from, to);
}
int
heim_any_cmp(const heim_any_set *p, const heim_any_set *q)
{
if (p->length != q->length)
return p->length - q->length;
return memcmp(p->data, q->data, p->length);
}

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

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).
* All rights reserved.
*
@@ -36,284 +36,538 @@
RCSID("$Id$");
static void
decode_primitive (const char *typename, const char *name)
decode_primitive (const char *typename, const char *name, const char *forwstr)
{
#if 0
fprintf (codefile,
"e = decode_%s(p, len, %s, &l);\n"
"FORW;\n",
"%s;\n",
typename,
name);
name,
forwstr);
#else
fprintf (codefile,
"e = der_get_%s(p, len, %s, &l);\n"
"if(e) %s;\np += l; len -= l; ret += l;\n",
typename,
name,
forwstr);
#endif
}
static int
is_primitive_type(int type)
{
switch(type) {
case TInteger:
case TBoolean:
case TOctetString:
case TBitString:
case TEnumerated:
case TGeneralizedTime:
case TGeneralString:
case TOID:
case TUTCTime:
case TUTF8String:
case TPrintableString:
case TIA5String:
case TBMPString:
case TUniversalString:
case TNull:
return 1;
default:
return 0;
}
}
static void
decode_type (const char *name, const Type *t)
find_tag (const Type *t,
Der_class *cl, Der_type *ty, unsigned *tag)
{
switch (t->type) {
case TType:
#if 0
decode_type (name, t->symbol->type);
#endif
fprintf (codefile,
"e = decode_%s(p, len, %s, &l);\n"
"FORW;\n",
t->symbol->gen_name, name);
case TBitString:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_BitString;
break;
case TBoolean:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_Boolean;
break;
case TChoice:
errx(1, "Cannot have recursive CHOICE");
case TEnumerated:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_Enumerated;
break;
case TGeneralString:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_GeneralString;
break;
case TGeneralizedTime:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_GeneralizedTime;
break;
case TIA5String:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_IA5String;
break;
case TInteger:
if(t->members == NULL)
decode_primitive ("integer", name);
else {
char *s;
asprintf(&s, "(int*)%s", name);
if(s == NULL)
errx (1, "out of memory");
decode_primitive ("integer", s);
free(s);
}
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_Integer;
break;
case TUInteger:
decode_primitive ("unsigned", name);
case TNull:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_Null;
break;
case TEnumerated:
decode_primitive ("enumerated", name);
case TOID:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_OID;
break;
case TOctetString:
decode_primitive ("octet_string", name);
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_OctetString;
break;
case TOID :
decode_primitive ("oid", name);
case TPrintableString:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_PrintableString;
break;
case TSequence:
case TSequenceOf:
*cl = ASN1_C_UNIV;
*ty = CONS;
*tag = UT_Sequence;
break;
case TSet:
case TSetOf:
*cl = ASN1_C_UNIV;
*ty = CONS;
*tag = UT_Set;
break;
case TTag:
*cl = t->tag.tagclass;
*ty = is_primitive_type(t->subtype->type) ? PRIM : CONS;
*tag = t->tag.tagvalue;
break;
case TType:
return find_tag(t->symbol->type, cl, ty, tag);
case TUTCTime:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_UTCTime;
break;
case TUTF8String:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_UTF8String;
break;
case TBMPString:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_BMPString;
break;
case TUniversalString:
*cl = ASN1_C_UNIV;
*ty = PRIM;
*tag = UT_UniversalString;
break;
default:
abort();
}
}
static int
decode_type (const char *name, const Type *t, int optional,
const char *forwstr)
{
switch (t->type) {
case TType: {
if (optional)
fprintf(codefile,
"%s = calloc(1, sizeof(*%s));\n"
"if (%s == NULL) %s;\n",
name, name, name, forwstr);
fprintf (codefile,
"e = decode_%s(p, len, %s, &l);\n",
t->symbol->gen_name, name);
if (optional) {
fprintf (codefile,
"if(e) {\n"
"free(%s);\n"
"%s = NULL;\n"
"} else {\n"
"p += l; len -= l; ret += l;\n"
"}\n",
name, name);
} else {
fprintf (codefile,
"if(e) %s;\n",
forwstr);
fprintf (codefile,
"p += l; len -= l; ret += l;\n");
}
break;
}
case TInteger:
if(t->members) {
char *s;
asprintf(&s, "(int*)%s", name);
if (s == NULL)
errx (1, "out of memory");
decode_primitive ("integer", s, forwstr);
free(s);
} else if (t->range == NULL) {
decode_primitive ("heim_integer", name, forwstr);
} else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
decode_primitive ("integer", name, forwstr);
} else if (t->range->min == 0 && t->range->max == UINT_MAX) {
decode_primitive ("unsigned", name, forwstr);
} else if (t->range->min == 0 && t->range->max == INT_MAX) {
decode_primitive ("unsigned", name, forwstr);
} else
errx(1, "%s: unsupported range %d -> %d",
name, t->range->min, t->range->max);
break;
case TBoolean:
decode_primitive ("boolean", name, forwstr);
break;
case TEnumerated:
decode_primitive ("enumerated", name, forwstr);
break;
case TOctetString:
decode_primitive ("octet_string", name, forwstr);
break;
case TBitString: {
Member *m;
int tag = -1;
int pos;
int pos = 0;
fprintf (codefile,
"e = der_match_tag_and_length (p, len, ASN1_C_UNIV, PRIM, UT_BitString,"
"&reallen, &l);\n"
"FORW;\n"
"if(len < reallen)\n"
"return ASN1_OVERRUN;\n"
"p++;\n"
"len--;\n"
"reallen--;\n"
"ret++;\n");
pos = 0;
for (m = t->members; m && tag != m->val; m = m->next) {
if (ASN1_TAILQ_EMPTY(t->members)) {
decode_primitive ("bit_string", name, forwstr);
break;
}
fprintf(codefile,
"if (len < 1) return ASN1_OVERRUN;\n"
"p++; len--; ret++;\n");
fprintf(codefile,
"do {\n"
"if (len < 1) break;\n");
ASN1_TAILQ_FOREACH(m, t->members, members) {
while (m->val / 8 > pos / 8) {
fprintf (codefile,
"p++; len--; reallen--; ret++;\n");
"p++; len--; ret++;\n"
"if (len < 1) break;\n");
pos += 8;
}
fprintf (codefile,
"%s->%s = (*p >> %d) & 1;\n",
"(%s)->%s = (*p >> %d) & 1;\n",
name, m->gen_name, 7 - m->val % 8);
if (tag == -1)
tag = m->val;
}
fprintf(codefile,
"} while(0);\n");
fprintf (codefile,
"p += reallen; len -= reallen; ret += reallen;\n");
"p += len; ret += len;\n");
break;
}
case TSequence: {
Member *m;
int tag = -1;
int fd_counter = unique_get_next();
int fd_counter_inner = unique_get_next();
if (t->members == NULL)
break;
fprintf (codefile,
"e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,"
"&reallen, &l);\n"
"FORW;\n"
"{\n"
"int dce_fix%d;\n"
"if((dce_fix%d = fix_dce(reallen, &len)) < 0)\n"
"return ASN1_BAD_FORMAT;\n",
fd_counter, fd_counter);
for (m = t->members; m && tag != m->val; m = m->next) {
ASN1_TAILQ_FOREACH(m, t->members, members) {
char *s;
asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
if (0 && m->type->type == TType){
if(m->optional)
fprintf (codefile,
"%s = malloc(sizeof(*%s));\n"
"if(%s == NULL) return ENOMEM;\n", s, s, s);
fprintf (codefile,
"e = decode_seq_%s(p, len, %d, %d, %s, &l);\n",
m->type->symbol->gen_name,
m->val,
m->optional,
s);
if(m->optional)
fprintf (codefile,
"if (e == ASN1_MISSING_FIELD) {\n"
"free(%s);\n"
"%s = NULL;\n"
"e = l = 0;\n"
"}\n",
s, s);
if (m->ellipsis)
continue;
fprintf (codefile, "FORW;\n");
}else{
fprintf (codefile, "{\n"
"size_t newlen, oldlen;\n\n"
"e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, %d, &l);\n",
m->val);
fprintf (codefile,
"if (e)\n");
if(m->optional)
/* XXX should look at e */
fprintf (codefile,
"%s = NULL;\n", s);
else
fprintf (codefile,
"return e;\n");
fprintf (codefile,
"else {\n");
fprintf (codefile,
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"e = der_get_length (p, len, &newlen, &l);\n"
"FORW;\n"
"{\n"
"int dce_fix%d;\n"
"oldlen = len;\n"
"if((dce_fix%d = fix_dce(newlen, &len)) < 0)"
"return ASN1_BAD_FORMAT;\n",
fd_counter_inner,
fd_counter_inner);
if (m->optional)
fprintf (codefile,
"%s = malloc(sizeof(*%s));\n"
"if(%s == NULL) return ENOMEM;\n", s, s, s);
decode_type (s, m->type);
fprintf (codefile,
"if(dce_fix%d){\n"
"e = der_match_tag_and_length (p, len, "
"(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
"FORW;\n"
"}else \n"
"len = oldlen - newlen;\n"
"}\n"
"}\n",
fd_counter_inner);
fprintf (codefile,
"}\n");
}
if (tag == -1)
tag = m->val;
asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&",
name, m->gen_name);
if (s == NULL)
errx(1, "malloc");
decode_type (s, m->type, m->optional, forwstr);
free (s);
}
fprintf(codefile,
"if(dce_fix%d){\n"
"e = der_match_tag_and_length (p, len, "
"(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
"FORW;\n"
"}\n"
"}\n",
fd_counter);
break;
}
case TSet: {
Member *m;
unsigned int memno;
if(t->members == NULL)
break;
fprintf(codefile, "{\n");
fprintf(codefile, "unsigned int members = 0;\n");
fprintf(codefile, "while(len > 0) {\n");
fprintf(codefile,
"Der_class class;\n"
"Der_type type;\n"
"int tag;\n"
"e = der_get_tag (p, len, &class, &type, &tag, NULL);\n"
"if(e) %s;\n", forwstr);
fprintf(codefile, "switch (MAKE_TAG(class, type, tag)) {\n");
memno = 0;
ASN1_TAILQ_FOREACH(m, t->members, members) {
char *s;
assert(m->type->type == TTag);
fprintf(codefile, "case MAKE_TAG(%s, %s, %s):\n",
classname(m->type->tag.tagclass),
is_primitive_type(m->type->subtype->type) ? "PRIM" : "CONS",
valuename(m->type->tag.tagclass, m->type->tag.tagvalue));
asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
if (s == NULL)
errx(1, "malloc");
if(m->optional)
fprintf(codefile,
"%s = calloc(1, sizeof(*%s));\n"
"if (%s == NULL) { e = ENOMEM; %s; }\n",
s, s, s, forwstr);
decode_type (s, m->type, 0, forwstr);
free (s);
fprintf(codefile, "members |= (1 << %d);\n", memno);
memno++;
fprintf(codefile, "break;\n");
}
fprintf(codefile,
"default:\n"
"return ASN1_MISPLACED_FIELD;\n"
"break;\n");
fprintf(codefile, "}\n");
fprintf(codefile, "}\n");
memno = 0;
ASN1_TAILQ_FOREACH(m, t->members, members) {
char *s;
asprintf (&s, "%s->%s", name, m->gen_name);
if (s == NULL)
errx(1, "malloc");
fprintf(codefile, "if((members & (1 << %d)) == 0)\n", memno);
if(m->optional)
fprintf(codefile, "%s = NULL;\n", s);
else if(m->defval)
gen_assign_defval(s, m->defval);
else
fprintf(codefile, "return ASN1_MISSING_FIELD;\n");
free(s);
memno++;
}
fprintf(codefile, "}\n");
break;
}
case TSetOf:
case TSequenceOf: {
char *n;
int oldret_counter = unique_get_next();
fprintf (codefile,
"e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,"
"&reallen, &l);\n"
"FORW;\n"
"if(len < reallen)\n"
"return ASN1_OVERRUN;\n"
"len = reallen;\n");
fprintf (codefile,
"{\n"
"size_t origlen = len;\n"
"int oldret%d = ret;\n"
"size_t oldret = ret;\n"
"void *tmp;\n"
"ret = 0;\n"
"(%s)->len = 0;\n"
"(%s)->val = NULL;\n"
"while(ret < origlen) {\n"
"tmp = realloc((%s)->val, "
" sizeof(*((%s)->val)) * ((%s)->len + 1));\n"
"if (tmp == NULL) { %s; }\n"
"(%s)->len++;\n"
"(%s)->val = realloc((%s)->val, sizeof(*((%s)->val)) * (%s)->len);\n",
oldret_counter, name, name, name, name, name, name, name);
"(%s)->val = tmp;\n",
name, name, name, name, name, forwstr, name, name);
asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name);
decode_type (n, t->subtype);
if (n == NULL)
errx(1, "malloc");
decode_type (n, t->subtype, 0, forwstr);
fprintf (codefile,
"len = origlen - ret;\n"
"}\n"
"ret += oldret%d;\n"
"}\n",
oldret_counter);
"ret += oldret;\n"
"}\n");
free (n);
break;
}
case TGeneralizedTime:
decode_primitive ("generalized_time", name);
decode_primitive ("generalized_time", name, forwstr);
break;
case TGeneralString:
decode_primitive ("general_string", name);
decode_primitive ("general_string", name, forwstr);
break;
case TTag:{
fprintf(codefile,
"{\n"
"int tagdatalen;\n"
"size_t oldlen;\n");
if(dce_fix)
fprintf(codefile,
"int dce_fix;\n");
fprintf(codefile, "e = der_match_tag_and_length(p, len, %s, %s, %s, "
"&tagdatalen, &l);\n",
classname(t->tag.tagclass),
is_primitive_type(t->subtype->type) ? "PRIM" : "CONS",
valuename(t->tag.tagclass, t->tag.tagvalue));
if(optional) {
fprintf(codefile,
"if(e) {\n"
"%s = NULL;\n"
"} else {\n"
"%s = calloc(1, sizeof(*%s));\n"
"if (%s == NULL) { e = ENOMEM; %s; }\n",
name, name, name, name, forwstr);
} else {
fprintf(codefile, "if(e) %s;\n", forwstr);
}
fprintf (codefile,
"p += l; len -= l; ret += l;\n"
"oldlen = len;\n");
if(dce_fix)
fprintf (codefile,
"if((dce_fix = _heim_fix_dce(tagdatalen, &len)) < 0)\n"
"{ e = ASN1_BAD_FORMAT; %s; }\n",
forwstr);
else
fprintf(codefile,
"if (tagdatalen > len) { e = ASN1_OVERRUN; %s; }\n"
"len = tagdatalen;\n", forwstr);
decode_type (name, t->subtype, 0, forwstr);
if(dce_fix)
fprintf(codefile,
"if(dce_fix){\n"
"e = der_match_tag_and_length (p, len, "
"(Der_class)0,(Der_type)0, UT_EndOfContent, "
"&tagdatalen, &l);\n"
"if(e) %s;\np += l; len -= l; ret += l;\n"
"} else \n", forwstr);
fprintf(codefile,
"len = oldlen - tagdatalen;\n");
if(optional)
fprintf(codefile,
"}\n");
fprintf(codefile,
"}\n");
break;
}
case TChoice: {
Member *m, *have_ellipsis = NULL;
const char *els = "";
if (t->members == NULL)
break;
ASN1_TAILQ_FOREACH(m, t->members, members) {
const Type *tt = m->type;
char *s;
Der_class cl;
Der_type ty;
unsigned tag;
if (m->ellipsis) {
have_ellipsis = m;
continue;
}
find_tag(tt, &cl, &ty, &tag);
fprintf(codefile,
"%sif (der_match_tag(p, len, %s, %s, %s, NULL) == 0) {\n",
els,
classname(cl),
ty ? "CONS" : "PRIM",
valuename(cl, tag));
asprintf (&s, "%s(%s)->u.%s", m->optional ? "" : "&",
name, m->gen_name);
if (s == NULL)
errx(1, "malloc");
decode_type (s, m->type, m->optional, forwstr);
free(s);
fprintf(codefile,
"}\n");
els = "else ";
}
if (have_ellipsis) {
fprintf(codefile,
"else {\n"
"(%s)->u.%s.data = calloc(1, len);\n"
"if ((%s)->u.%s.data == NULL) {\n"
"e = ENOMEM; %s;\n"
"}\n"
"(%s)->u.%s.length = len;\n"
"memcpy((%s)->u.%s.data, p, len);\n"
"(%s)->element = %s;\n"
"p += len;\n"
"ret += len;\n"
"len -= len;\n"
"}\n",
name, have_ellipsis->gen_name,
name, have_ellipsis->gen_name,
forwstr,
name, have_ellipsis->gen_name,
name, have_ellipsis->gen_name,
name, have_ellipsis->label);
} else {
fprintf(codefile,
"else {\n"
"e = ASN1_PARSE_ERROR;\n"
"%s;\n"
"}\n",
forwstr);
}
break;
}
case TUTCTime:
decode_primitive ("utctime", name, forwstr);
break;
case TUTF8String:
decode_primitive ("utf8string", name);
decode_primitive ("utf8string", name, forwstr);
break;
case TPrintableString:
decode_primitive ("printable_string", name, forwstr);
break;
case TIA5String:
decode_primitive ("ia5_string", name, forwstr);
break;
case TBMPString:
decode_primitive ("bmp_string", name, forwstr);
break;
case TUniversalString:
decode_primitive ("universal_string", name, forwstr);
break;
case TNull:
fprintf (codefile,
"e = decode_nulltype(p, len, &l);\n"
"FORW;\n");
fprintf (codefile, "/* NULL */\n");
break;
case TApplication:
fprintf (codefile,
"e = der_match_tag_and_length (p, len, ASN1_C_APPL, CONS, %d, "
"&reallen, &l);\n"
"FORW;\n"
"{\n"
"int dce_fix;\n"
"if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
"return ASN1_BAD_FORMAT;\n",
t->application);
decode_type (name, t->subtype);
fprintf(codefile,
"if(dce_fix){\n"
"e = der_match_tag_and_length (p, len, "
"(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
"FORW;\n"
"}\n"
"}\n");
break;
case TBoolean:
decode_primitive ("boolean", name);
case TOID:
decode_primitive ("oid", name, forwstr);
break;
default :
abort ();
}
return 0;
}
void
generate_type_decode (const Symbol *s)
{
unique_reset();
int preserve = preserve_type(s->name) ? TRUE : FALSE;
fprintf (headerfile,
"int "
"decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
s->gen_name, s->gen_name);
fprintf (codefile, "#define FORW "
"if(e) goto fail; "
"p += l; "
"len -= l; "
"ret += l\n\n");
fprintf (codefile, "int\n"
"decode_%s(const unsigned char *p,"
" size_t len, %s *data, size_t *size)\n"
@@ -322,28 +576,45 @@ generate_type_decode (const Symbol *s)
switch (s->type->type) {
case TInteger:
case TUInteger:
case TBoolean:
case TOctetString:
case TOID:
case TGeneralizedTime:
case TGeneralString:
case TUTF8String:
case TPrintableString:
case TIA5String:
case TBMPString:
case TUniversalString:
case TUTCTime:
case TNull:
case TEnumerated:
case TBitString:
case TSequence:
case TSequenceOf:
case TApplication:
case TSet:
case TSetOf:
case TTag:
case TType:
case TChoice:
fprintf (codefile,
"size_t ret = 0, reallen;\n"
"size_t l;\n"
"int e;\n\n");
"int e;\n");
if (preserve)
fprintf (codefile, "const unsigned char *begin = p;\n");
fprintf (codefile, "\n");
fprintf (codefile, "memset(data, 0, sizeof(*data));\n");
fprintf (codefile, "reallen = 0;\n"); /* hack to avoid `unused variable' */
decode_type ("data", s->type);
decode_type ("data", s->type, 0, "goto fail");
if (preserve)
fprintf (codefile,
"data->_save.data = calloc(1, ret);\n"
"if (data->_save.data == NULL) { e = ENOMEM; goto fail; }\n"
"data->_save.length = ret;\n"
"memcpy(data->_save.data, begin, ret);\n");
fprintf (codefile,
"if(size) *size = ret;\n"
"return 0;\n");
@@ -358,62 +629,3 @@ generate_type_decode (const Symbol *s)
}
fprintf (codefile, "}\n\n");
}
void
generate_seq_type_decode (const Symbol *s)
{
fprintf (headerfile,
"int decode_seq_%s(const unsigned char *, size_t, int, int, "
"%s *, size_t *);\n",
s->gen_name, s->gen_name);
fprintf (codefile, "int\n"
"decode_seq_%s(const unsigned char *p, size_t len, int tag, "
"int optional, %s *data, size_t *size)\n"
"{\n",
s->gen_name, s->gen_name);
fprintf (codefile,
"size_t newlen, oldlen;\n"
"size_t l, ret = 0;\n"
"int e;\n"
"int dce_fix;\n");
fprintf (codefile,
"e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, tag, &l);\n"
"if (e)\n"
"return e;\n");
fprintf (codefile,
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"e = der_get_length(p, len, &newlen, &l);\n"
"if (e)\n"
"return e;\n"
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"oldlen = len;\n"
"if ((dce_fix = fix_dce(newlen, &len)) < 0)\n"
"return ASN1_BAD_FORMAT;\n"
"e = decode_%s(p, len, data, &l);\n"
"if (e)\n"
"return e;\n"
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"if (dce_fix) {\n"
"size_t reallen;\n\n"
"e = der_match_tag_and_length(p, len, "
"(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
"if (e)\n"
"return e;\n"
"ret += l;\n"
"}\n",
s->gen_name);
fprintf (codefile,
"if(size) *size = ret;\n"
"return 0;\n");
fprintf (codefile, "}\n\n");
}

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).
* All rights reserved.
*
@@ -39,15 +39,76 @@ static void
encode_primitive (const char *typename, const char *name)
{
fprintf (codefile,
"e = encode_%s(p, len, %s, &l);\n"
"BACK;\n",
"e = der_put_%s(p, len, %s, &l);\n"
"if (e) return e;\np -= l; len -= l; ret += l;\n\n",
typename,
name);
}
static void
const char *
classname(Der_class class)
{
const char *cn[] = { "ASN1_C_UNIV", "ASN1_C_APPL",
"ASN1_C_CONTEXT", "ASN1_C_PRIV" };
if(class < ASN1_C_UNIV || class > ASN1_C_PRIVATE)
return "???";
return cn[class];
}
const char *
valuename(Der_class class, int value)
{
static char s[32];
struct {
int value;
char *s;
} *p, values[] = {
#define X(Y) { Y, #Y }
X(UT_BMPString),
X(UT_BitString),
X(UT_Boolean),
X(UT_EmbeddedPDV),
X(UT_Enumerated),
X(UT_External),
X(UT_GeneralString),
X(UT_GeneralizedTime),
X(UT_GraphicString),
X(UT_IA5String),
X(UT_Integer),
X(UT_Null),
X(UT_NumericString),
X(UT_OID),
X(UT_ObjectDescriptor),
X(UT_OctetString),
X(UT_PrintableString),
X(UT_Real),
X(UT_RelativeOID),
X(UT_Sequence),
X(UT_Set),
X(UT_TeletexString),
X(UT_UTCTime),
X(UT_UTF8String),
X(UT_UniversalString),
X(UT_VideotexString),
X(UT_VisibleString),
#undef X
{ -1, NULL }
};
if(class == ASN1_C_UNIV) {
for(p = values; p->value != -1; p++)
if(p->value == value)
return p->s;
}
snprintf(s, sizeof(s), "%d", value);
return s;
}
static int
encode_type (const char *name, const Type *t)
{
int constructed = 1;
switch (t->type) {
case TType:
#if 0
@@ -55,45 +116,60 @@ encode_type (const char *name, const Type *t)
#endif
fprintf (codefile,
"e = encode_%s(p, len, %s, &l);\n"
"BACK;\n",
"if (e) return e;\np -= l; len -= l; ret += l;\n\n",
t->symbol->gen_name, name);
break;
case TInteger:
if(t->members == NULL)
encode_primitive ("integer", name);
else {
if(t->members) {
char *s;
asprintf(&s, "(const int*)%s", name);
if(s == NULL)
errx(1, "out of memory");
encode_primitive ("integer", s);
free(s);
}
} else if (t->range == NULL) {
encode_primitive ("heim_integer", name);
} else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
encode_primitive ("integer", name);
} else if (t->range->min == 0 && t->range->max == UINT_MAX) {
encode_primitive ("unsigned", name);
} else if (t->range->min == 0 && t->range->max == INT_MAX) {
encode_primitive ("unsigned", name);
} else
errx(1, "%s: unsupported range %d -> %d",
name, t->range->min, t->range->max);
constructed = 0;
break;
case TUInteger:
encode_primitive ("unsigned", name);
case TBoolean:
encode_primitive ("boolean", name);
constructed = 0;
break;
case TOctetString:
encode_primitive ("octet_string", name);
break;
case TOID :
encode_primitive ("oid", name);
constructed = 0;
break;
case TBitString: {
Member *m;
int pos;
int rest;
int tag = -1;
if (t->members == NULL)
if (ASN1_TAILQ_EMPTY(t->members)) {
encode_primitive("bit_string", name);
constructed = 0;
break;
}
fprintf (codefile, "{\n"
"unsigned char c = 0;\n");
if (!rfc1510_bitstring)
fprintf (codefile,
"int bit_set = 0;\n");
#if 0
pos = t->members->prev->val;
/* fix for buggy MIT (and OSF?) code */
if (pos > 31)
abort ();
#endif
/*
* It seems that if we do not always set pos to 31 here, the MIT
* code will do the wrong thing.
@@ -101,139 +177,293 @@ encode_type (const char *name, const Type *t)
* I hate ASN.1 (and DER), but I hate it even more when everybody
* has to screw it up differently.
*/
pos = 31;
rest = 7 - (pos % 8);
pos = ASN1_TAILQ_LAST(t->members, memhead)->val;
if (rfc1510_bitstring) {
if (pos < 31)
pos = 31;
rest = 7 - (pos % 8);
} else
rest = 0;
for (m = t->members->prev; m && tag != m->val; m = m->prev) {
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
while (m->val / 8 < pos / 8) {
if (!rfc1510_bitstring)
fprintf (codefile,
"if (c != 0 || bit_set) {\n");
fprintf (codefile,
"if (len < 1) return ASN1_OVERFLOW;\n"
"*p-- = c; len--; ret++;\n"
"c = 0;\n");
if (!rfc1510_bitstring)
fprintf (codefile,
"bit_set = 1;\n"
"}\n");
pos -= 8;
}
fprintf (codefile,
"if(%s->%s) c |= 1<<%d;\n", name, m->gen_name,
7 - m->val % 8);
if (tag == -1)
tag = m->val;
"if((%s)->%s) {\n"
"c |= 1<<%d;\n",
name, m->gen_name, 7 - m->val % 8);
if (!rfc1510_bitstring)
rest = 7 - m->val % 8;
fprintf (codefile,
"}\n");
}
if (!rfc1510_bitstring)
fprintf (codefile,
"if (c != 0 || bit_set) {\n");
fprintf (codefile,
"*p-- = c;\n"
"if (len < 1) return ASN1_OVERFLOW;\n"
"*p-- = c; len--; ret++;\n");
if (!rfc1510_bitstring)
fprintf (codefile,
"}\n");
fprintf (codefile,
"if (len < 1) return ASN1_OVERFLOW;\n"
"*p-- = %d;\n"
"len -= 2;\n"
"ret += 2;\n"
"}\n\n"
"e = der_put_length_and_tag (p, len, ret, ASN1_C_UNIV, PRIM,"
"UT_BitString, &l);\n"
"BACK;\n",
"len -= 1;\n"
"ret += 1;\n"
"}\n\n",
rest);
constructed = 0;
break;
}
case TEnumerated : {
encode_primitive ("enumerated", name);
constructed = 0;
break;
}
case TSet:
case TSequence: {
Member *m;
int tag = -1;
int oldret_counter = unique_get_next();
if (t->members == NULL)
break;
for (m = t->members->prev; m && tag != m->val; m = m->prev) {
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
char *s;
if (m->ellipsis)
continue;
asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
if (s == NULL)
errx(1, "malloc");
fprintf(codefile, "/* %s */\n", m->name);
if (m->optional)
fprintf (codefile,
"if(%s)\n",
"if(%s) ",
s);
#if 1
fprintf (codefile, "{\n"
"int oldret%d = ret;\n"
"ret = 0;\n",
oldret_counter);
#endif
else if(m->defval)
gen_compare_defval(s + 1, m->defval);
fprintf (codefile, "{\n");
fprintf (codefile, "size_t oldret = ret;\n");
fprintf (codefile, "ret = 0;\n");
encode_type (s, m->type);
fprintf (codefile,
"e = der_put_length_and_tag (p, len, ret, ASN1_C_CONTEXT, CONS, "
"%d, &l);\n"
"BACK;\n",
m->val);
#if 1
fprintf (codefile,
"ret += oldret%d;\n"
"}\n",
oldret_counter);
#endif
if (tag == -1)
tag = m->val;
fprintf (codefile, "ret += oldret;\n");
fprintf (codefile, "}\n");
free (s);
}
break;
}
case TSetOf: {
fprintf(codefile,
"{\n"
"struct heim_octet_string *val;\n"
"size_t elen, totallen = 0;\n"
"int eret;\n");
fprintf(codefile,
"val = malloc(sizeof(val[0]) * (%s)->len);\n"
"if (val == NULL && (%s)->len != 0) return ENOMEM;\n",
name, name);
fprintf(codefile,
"for(i = 0; i < (%s)->len; i++) {\n",
name);
fprintf(codefile,
"ASN1_MALLOC_ENCODE(%s, val[i].data, "
"val[i].length, &(%s)->val[i], &elen, eret);\n",
t->subtype->symbol->gen_name,
name);
fprintf(codefile,
"if(eret) {\n"
"i--;\n"
"while (i >= 0) {\n"
"free(val[i].data);\n"
"i--;\n"
"}\n"
"free(val);\n"
"return eret;\n"
"}\n"
"totallen += elen;\n"
"}\n");
fprintf(codefile,
"if (totallen > len) {\n"
"for (i = 0; i < (%s)->len; i++) {\n"
"free(val[i].data);\n"
"}\n"
"free(val);\n"
"return ASN1_OVERFLOW;\n"
"}\n",
name);
fprintf(codefile,
"qsort(val, (%s)->len, sizeof(val[0]), _heim_der_set_sort);\n",
name);
fprintf (codefile,
"e = der_put_length_and_tag (p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);\n"
"BACK;\n");
"for(i = (%s)->len - 1; i >= 0; --i) {\n"
"p -= val[i].length;\n"
"ret += val[i].length;\n"
"memcpy(p + 1, val[i].data, val[i].length);\n"
"free(val[i].data);\n"
"}\n"
"free(val);\n"
"}\n",
name);
break;
}
case TSequenceOf: {
int oldret_counter = unique_get_next();
char *n;
fprintf (codefile,
"for(i = (%s)->len - 1; i >= 0; --i) {\n"
#if 1
"int oldret%d = ret;\n"
"size_t oldret = ret;\n"
"ret = 0;\n",
#else
,
#endif
name, oldret_counter);
name);
asprintf (&n, "&(%s)->val[i]", name);
if (n == NULL)
errx(1, "malloc");
encode_type (n, t->subtype);
fprintf (codefile,
#if 1
"ret += oldret%d;\n"
#endif
"}\n"
"e = der_put_length_and_tag (p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);\n"
"BACK;\n"
#if 1
, oldret_counter
#endif
);
"ret += oldret;\n"
"}\n");
free (n);
break;
}
case TGeneralizedTime:
encode_primitive ("generalized_time", name);
constructed = 0;
break;
case TGeneralString:
encode_primitive ("general_string", name);
constructed = 0;
break;
case TTag: {
int c = encode_type (name, t->subtype);
fprintf (codefile,
"e = der_put_length_and_tag (p, len, ret, %s, %s, %s, &l);\n"
"if (e) return e;\np -= l; len -= l; ret += l;\n\n",
classname(t->tag.tagclass),
c ? "CONS" : "PRIM",
valuename(t->tag.tagclass, t->tag.tagvalue));
break;
}
case TChoice:{
Member *m, *have_ellipsis = NULL;
char *s;
if (t->members == NULL)
break;
fprintf(codefile, "\n");
asprintf (&s, "(%s)", name);
if (s == NULL)
errx(1, "malloc");
fprintf(codefile, "switch(%s->element) {\n", s);
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
char *s2;
if (m->ellipsis) {
have_ellipsis = m;
continue;
}
fprintf (codefile, "case %s: {", m->label);
asprintf(&s2, "%s(%s)->u.%s", m->optional ? "" : "&",
s, m->gen_name);
if (s2 == NULL)
errx(1, "malloc");
if (m->optional)
fprintf (codefile, "if(%s) {\n", s2);
fprintf (codefile, "size_t oldret;\n");
fprintf (codefile, "oldret = ret;\n");
fprintf (codefile, "ret = 0;\n");
constructed = encode_type (s2, m->type);
fprintf (codefile, "ret += oldret;\n");
if(m->optional)
fprintf (codefile, "}\n");
fprintf(codefile, "break;\n");
fprintf(codefile, "}\n");
free (s2);
}
free (s);
if (have_ellipsis) {
fprintf(codefile,
"case %s: {\n"
"if (len < %s->u.%s.length)\n"
"return ASN1_OVERFLOW;\n"
"p -= %s->u.%s.length;\n"
"ret += %s->u.%s.length;\n"
"memcpy(p + 1, %s->u.%s.data, %s->u.%s.length);\n"
"break;\n"
"}\n",
have_ellipsis->label,
name, have_ellipsis->gen_name,
name, have_ellipsis->gen_name,
name, have_ellipsis->gen_name,
name, have_ellipsis->gen_name,
name, have_ellipsis->gen_name);
}
fprintf(codefile, "};\n");
break;
}
case TOID:
encode_primitive ("oid", name);
constructed = 0;
break;
case TUTCTime:
encode_primitive ("utctime", name);
constructed = 0;
break;
case TUTF8String:
encode_primitive ("utf8string", name);
constructed = 0;
break;
case TPrintableString:
encode_primitive ("printable_string", name);
constructed = 0;
break;
case TIA5String:
encode_primitive ("ia5_string", name);
constructed = 0;
break;
case TBMPString:
encode_primitive ("bmp_string", name);
constructed = 0;
break;
case TUniversalString:
encode_primitive ("universal_string", name);
constructed = 0;
break;
case TNull:
fprintf (codefile,
"e = encode_nulltype(p, len, &l);\n"
"BACK;\n");
break;
case TApplication:
encode_type (name, t->subtype);
fprintf (codefile,
"e = der_put_length_and_tag (p, len, ret, ASN1_C_APPL, CONS, %d, &l);\n"
"BACK;\n",
t->application);
break;
case TBoolean:
encode_primitive ("boolean", name);
fprintf (codefile, "/* NULL */\n");
constructed = 0;
break;
default:
abort ();
}
return constructed;
}
void
@@ -244,9 +474,6 @@ generate_type_encode (const Symbol *s)
"encode_%s(unsigned char *, size_t, const %s *, size_t *);\n",
s->gen_name, s->gen_name);
fprintf (codefile, "#define BACK if (e) return e; p -= l; len -= l; ret += l\n\n");
fprintf (codefile, "int\n"
"encode_%s(unsigned char *p, size_t len,"
" const %s *data, size_t *size)\n"
@@ -255,20 +482,27 @@ generate_type_encode (const Symbol *s)
switch (s->type->type) {
case TInteger:
case TUInteger:
case TBoolean:
case TOctetString:
case TGeneralizedTime:
case TGeneralString:
case TUTCTime:
case TUTF8String:
case TPrintableString:
case TIA5String:
case TBMPString:
case TUniversalString:
case TNull:
case TBitString:
case TEnumerated:
case TOID:
case TSequence:
case TSequenceOf:
case TApplication:
case TSet:
case TSetOf:
case TTag:
case TType:
case TChoice:
fprintf (codefile,
"size_t ret = 0;\n"
"size_t l;\n"

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

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

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).
* All rights reserved.
*
@@ -43,7 +43,22 @@ length_primitive (const char *typename,
fprintf (codefile, "%s += length_%s(%s);\n", variable, typename, name);
}
static void
static size_t
length_tag(unsigned int tag)
{
size_t len = 0;
if(tag <= 30)
return 1;
while(tag) {
tag /= 128;
len++;
}
return len + 1;
}
static int
length_type (const char *name, const Type *t, const char *variable)
{
switch (t->type) {
@@ -55,19 +70,28 @@ length_type (const char *name, const Type *t, const char *variable)
variable, t->symbol->gen_name, name);
break;
case TInteger:
if(t->members == NULL)
length_primitive ("integer", name, variable);
else {
char *s;
asprintf(&s, "(const int*)%s", name);
if(s == NULL)
if(t->members) {
char *s;
asprintf(&s, "(const int*)%s", name);
if(s == NULL)
errx (1, "out of memory");
length_primitive ("integer", s, variable);
free(s);
}
length_primitive ("integer", s, variable);
free(s);
} else if (t->range == NULL) {
length_primitive ("heim_integer", name, variable);
} else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
length_primitive ("integer", name, variable);
} else if (t->range->min == 0 && t->range->max == UINT_MAX) {
length_primitive ("unsigned", name, variable);
} else if (t->range->min == 0 && t->range->max == INT_MAX) {
length_primitive ("unsigned", name, variable);
} else
errx(1, "%s: unsupported range %d -> %d",
name, t->range->min, t->range->max);
break;
case TUInteger:
length_primitive ("unsigned", name, variable);
case TBoolean:
fprintf (codefile, "%s += 1;\n", variable);
break;
case TEnumerated :
length_primitive ("enumerated", name, variable);
@@ -75,71 +99,112 @@ length_type (const char *name, const Type *t, const char *variable)
case TOctetString:
length_primitive ("octet_string", name, variable);
break;
case TOID :
length_primitive ("oid", name, variable);
break;
case TBitString: {
/*
* XXX - Hope this is correct
* look at TBitString case in `encode_type'
*/
fprintf (codefile, "%s += 7;\n", variable);
if (ASN1_TAILQ_EMPTY(t->members))
length_primitive("bit_string", name, variable);
else {
if (!rfc1510_bitstring) {
Member *m;
int pos = ASN1_TAILQ_LAST(t->members, memhead)->val;
fprintf(codefile,
"do {\n");
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
while (m->val / 8 < pos / 8) {
pos -= 8;
}
fprintf (codefile,
"if((%s)->%s) { %s += %d; break; }\n",
name, m->gen_name, variable, (pos + 8) / 8);
}
fprintf(codefile,
"} while(0);\n");
fprintf (codefile, "%s += 1;\n", variable);
} else {
fprintf (codefile, "%s += 5;\n", variable);
}
}
break;
}
case TSequence: {
Member *m;
int tag = -1;
int oldret_counter = unique_get_next();
case TSet:
case TSequence:
case TChoice: {
Member *m, *have_ellipsis = NULL;
if (t->members == NULL)
break;
for (m = t->members; m && tag != m->val; m = m->next) {
if(t->type == TChoice)
fprintf (codefile, "switch((%s)->element) {\n", name);
ASN1_TAILQ_FOREACH(m, t->members, members) {
char *s;
asprintf (&s, "%s(%s)->%s",
m->optional ? "" : "&", name, m->gen_name);
if (m->ellipsis) {
have_ellipsis = m;
continue;
}
if(t->type == TChoice)
fprintf(codefile, "case %s:\n", m->label);
asprintf (&s, "%s(%s)->%s%s",
m->optional ? "" : "&", name,
t->type == TChoice ? "u." : "", m->gen_name);
if (s == NULL)
errx(1, "malloc");
if (m->optional)
fprintf (codefile, "if(%s)", s);
else if(m->defval)
gen_compare_defval(s + 1, m->defval);
fprintf (codefile, "{\n"
"int oldret%d = %s;\n"
"%s = 0;\n", oldret_counter, variable, variable);
"size_t oldret = %s;\n"
"%s = 0;\n", variable, variable);
length_type (s, m->type, "ret");
fprintf (codefile, "%s += 1 + length_len(%s) + oldret%d;\n",
variable, variable, oldret_counter);
fprintf (codefile, "ret += oldret;\n");
fprintf (codefile, "}\n");
if (tag == -1)
tag = m->val;
free (s);
if(t->type == TChoice)
fprintf(codefile, "break;\n");
}
if(t->type == TChoice) {
if (have_ellipsis)
fprintf(codefile,
"case %s:\n"
"ret += %s->u.%s.length;\n"
"break;\n",
have_ellipsis->label,
name,
have_ellipsis->gen_name);
fprintf (codefile, "}\n"); /* switch */
}
fprintf (codefile,
"%s += 1 + length_len(%s);\n", variable, variable);
break;
}
case TSetOf:
case TSequenceOf: {
char *n;
int oldret_counter = unique_get_next();
int oldret_counter_inner = unique_get_next();
fprintf (codefile,
"{\n"
"int oldret%d = %s;\n"
"int oldret = %s;\n"
"int i;\n"
"%s = 0;\n",
oldret_counter, variable, variable);
variable, variable);
fprintf (codefile, "for(i = (%s)->len - 1; i >= 0; --i){\n", name);
fprintf (codefile, "int oldret%d = %s;\n"
"%s = 0;\n", oldret_counter_inner, variable, variable);
fprintf (codefile, "int oldret = %s;\n"
"%s = 0;\n", variable, variable);
asprintf (&n, "&(%s)->val[i]", name);
if (n == NULL)
errx(1, "malloc");
length_type(n, t->subtype, variable);
fprintf (codefile, "%s += oldret%d;\n",
variable, oldret_counter_inner);
fprintf (codefile, "%s += oldret;\n",
variable);
fprintf (codefile, "}\n");
fprintf (codefile,
"%s += 1 + length_len(%s) + oldret%d;\n"
"}\n", variable, variable, oldret_counter);
"%s += oldret;\n"
"}\n", variable);
free(n);
break;
}
@@ -149,28 +214,43 @@ length_type (const char *name, const Type *t, const char *variable)
case TGeneralString:
length_primitive ("general_string", name, variable);
break;
case TUTCTime:
length_primitive ("utctime", name, variable);
break;
case TUTF8String:
length_primitive ("utf8string", name, variable);
break;
case TPrintableString:
length_primitive ("printable_string", name, variable);
break;
case TIA5String:
length_primitive ("ia5_string", name, variable);
break;
case TBMPString:
length_primitive ("bmp_string", name, variable);
break;
case TUniversalString:
length_primitive ("universal_string", name, variable);
break;
case TNull:
fprintf (codefile, "%s += length_nulltype();\n", variable);
fprintf (codefile, "/* NULL */\n");
break;
case TApplication:
case TTag:
length_type (name, t->subtype, variable);
fprintf (codefile, "ret += 1 + length_len (ret);\n");
fprintf (codefile, "ret += %d + length_len (ret);\n", length_tag(t->tag.tagvalue));
break;
case TBoolean:
length_primitive ("boolean", name, variable);
case TOID:
length_primitive ("oid", name, variable);
break;
default :
abort ();
}
return 0;
}
void
generate_type_length (const Symbol *s)
{
unique_reset();
fprintf (headerfile,
"size_t length_%s(const %s *);\n",
s->gen_name, s->gen_name);

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).
* All rights reserved.
*
@@ -51,6 +51,8 @@
#include <roken.h>
#include "hash.h"
#include "symbol.h"
#include "asn1-common.h"
#include "der.h"
void generate_type (const Symbol *);
void generate_constant (const Symbol *);
@@ -61,10 +63,14 @@ void generate_type_free (const Symbol *s);
void generate_type_length (const Symbol *s);
void generate_type_copy (const Symbol *s);
void generate_type_maybe (const Symbol *s);
void generate_glue (const Symbol *s);
void generate_glue (const Type *, const char*);
const char *classname(Der_class);
const char *valuename(Der_class class, int);
void gen_compare_defval(const char *var, struct value *val);
void gen_assign_defval(const char *var, struct value *val);
void unique_reset(void);
int unique_get_next(void);
void init_generate (const char *filename, const char *basename);
const char *get_filename (void);
@@ -72,6 +78,12 @@ void close_generate(void);
void add_import(const char *module);
int yyparse(void);
int preserve_type(const char *);
extern FILE *headerfile, *codefile, *logfile;
extern int dce_fix;
extern int rfc1510_bitstring;
extern int error_flag;
#endif /* __GEN_LOCL_H__ */

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).
* All rights reserved.
*
@@ -34,12 +34,8 @@
#ifndef __HEIM_ANY_H__
#define __HEIM_ANY_H__ 1
typedef struct heim_any {
size_t length;
void *data;
} heim_any;
typedef struct heim_any heim_any_set;
typedef struct heim_octet_string heim_any;
typedef struct heim_octet_string heim_any_set;
int encode_heim_any(unsigned char *, size_t, const heim_any *, size_t *);
int decode_heim_any(const unsigned char *, size_t, heim_any *, size_t *);
@@ -54,5 +50,6 @@ int decode_heim_any_set(const unsigned char *, size_t,
void free_heim_any_set(heim_any_set *);
size_t length_heim_any_set(const heim_any_set *);
int copy_heim_any_set(const heim_any_set *, heim_any_set *);
int heim_any_cmp(const heim_any_set *, const heim_any_set *);
#endif /* __HEIM_ANY_H__ */

View File

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

View File

@@ -37,5 +37,6 @@
void error_message (const char *, ...)
__attribute__ ((format (printf, 1, 2)));
extern int error_flag;
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).
* All rights reserved.
*
@@ -52,62 +52,118 @@
static unsigned lineno = 1;
#define YY_NO_UNPUT
#undef ECHO
static void handle_comment(int type);
static char *handle_string(void);
%}
%%
INTEGER { return INTEGER; }
BOOLEAN { return BOOLEAN; }
IMPORTS { return IMPORTS; }
FROM { return FROM; }
SEQUENCE { return SEQUENCE; }
CHOICE { return CHOICE; }
OF { return OF; }
OCTET { return OCTET; }
STRING { return STRING; }
GeneralizedTime { return GeneralizedTime; }
GeneralString { return GeneralString; }
UTF8String { return UTF8String; }
NULL { return NULLTYPE; }
BIT { return BIT; }
APPLICATION { return APPLICATION; }
OPTIONAL { return OPTIONAL; }
BEGIN { return TBEGIN; }
END { return END; }
DEFAULT { return DEFAULT; }
DEFINITIONS { return DEFINITIONS; }
ENUMERATED { return ENUMERATED; }
EXTERNAL { return EXTERNAL; }
OBJECT { return OBJECT; }
IDENTIFIER { return IDENTIFIER; }
[-,;{}()|\"] { return *yytext; }
ABSENT { return kw_ABSENT; }
ABSTRACT-SYNTAX { return kw_ABSTRACT_SYNTAX; }
ALL { return kw_ALL; }
APPLICATION { return kw_APPLICATION; }
AUTOMATIC { return kw_AUTOMATIC; }
BEGIN { return kw_BEGIN; }
BIT { return kw_BIT; }
BMPString { return kw_BMPString; }
BOOLEAN { return kw_BOOLEAN; }
BY { return kw_BY; }
CHARACTER { return kw_CHARACTER; }
CHOICE { return kw_CHOICE; }
CLASS { return kw_CLASS; }
COMPONENT { return kw_COMPONENT; }
COMPONENTS { return kw_COMPONENTS; }
CONSTRAINED { return kw_CONSTRAINED; }
CONTAINING { return kw_CONTAINING; }
DEFAULT { return kw_DEFAULT; }
DEFINITIONS { return kw_DEFINITIONS; }
EMBEDDED { return kw_EMBEDDED; }
ENCODED { return kw_ENCODED; }
END { return kw_END; }
ENUMERATED { return kw_ENUMERATED; }
EXCEPT { return kw_EXCEPT; }
EXPLICIT { return kw_EXPLICIT; }
EXPORTS { return kw_EXPORTS; }
EXTENSIBILITY { return kw_EXTENSIBILITY; }
EXTERNAL { return kw_EXTERNAL; }
FALSE { return kw_FALSE; }
FROM { return kw_FROM; }
GeneralString { return kw_GeneralString; }
GeneralizedTime { return kw_GeneralizedTime; }
GraphicString { return kw_GraphicString; }
IA5String { return kw_IA5String; }
IDENTIFIER { return kw_IDENTIFIER; }
IMPLICIT { return kw_IMPLICIT; }
IMPLIED { return kw_IMPLIED; }
IMPORTS { return kw_IMPORTS; }
INCLUDES { return kw_INCLUDES; }
INSTANCE { return kw_INSTANCE; }
INTEGER { return kw_INTEGER; }
INTERSECTION { return kw_INTERSECTION; }
ISO646String { return kw_ISO646String; }
MAX { return kw_MAX; }
MIN { return kw_MIN; }
MINUS-INFINITY { return kw_MINUS_INFINITY; }
NULL { return kw_NULL; }
NumericString { return kw_NumericString; }
OBJECT { return kw_OBJECT; }
OCTET { return kw_OCTET; }
OF { return kw_OF; }
OPTIONAL { return kw_OPTIONAL; }
ObjectDescriptor { return kw_ObjectDescriptor; }
PATTERN { return kw_PATTERN; }
PDV { return kw_PDV; }
PLUS-INFINITY { return kw_PLUS_INFINITY; }
PRESENT { return kw_PRESENT; }
PRIVATE { return kw_PRIVATE; }
PrintableString { return kw_PrintableString; }
REAL { return kw_REAL; }
RELATIVE_OID { return kw_RELATIVE_OID; }
SEQUENCE { return kw_SEQUENCE; }
SET { return kw_SET; }
SIZE { return kw_SIZE; }
STRING { return kw_STRING; }
SYNTAX { return kw_SYNTAX; }
T61String { return kw_T61String; }
TAGS { return kw_TAGS; }
TRUE { return kw_TRUE; }
TYPE-IDENTIFIER { return kw_TYPE_IDENTIFIER; }
TeletexString { return kw_TeletexString; }
UNION { return kw_UNION; }
UNIQUE { return kw_UNIQUE; }
UNIVERSAL { return kw_UNIVERSAL; }
UTCTime { return kw_UTCTime; }
UTF8String { return kw_UTF8String; }
UniversalString { return kw_UniversalString; }
VideotexString { return kw_VideotexString; }
VisibleString { return kw_VisibleString; }
WITH { return kw_WITH; }
[-,;{}()|] { return *yytext; }
"[" { return *yytext; }
"]" { return *yytext; }
::= { return EEQUAL; }
-- { handle_comment(0); }
\/\* { handle_comment(1); }
0x[0-9A-Fa-f]+|[0-9]+ { char *e, *y = yytext;
"\"" { yylval.name = handle_string(); return STRING; }
-?0x[0-9A-Fa-f]+|-?[0-9]+ { char *e, *y = yytext;
yylval.constant = strtol((const char *)yytext,
&e, 0);
if(e == y)
error_message("malformed constant (%s)", yytext);
else
return CONSTANT;
return NUMBER;
}
[A-Za-z][-A-Za-z0-9_]* {
yylval.name = strdup ((const char *)yytext);
return IDENT;
yylval.name = estrdup ((const char *)yytext);
return IDENTIFIER;
}
[ \t] ;
\n { ++lineno; }
\.\.\. { return DOTDOTDOT; }
\.\. { return DOTDOT; }
\.\.\. { return ELLIPSIS; }
\.\. { return RANGE; }
. { error_message("Ignoring char(%c)\n", *yytext); }
%%
@@ -128,6 +184,7 @@ error_message (const char *format, ...)
fprintf (stderr, "%s:%d: ", get_filename(), lineno);
vfprintf (stderr, format, args);
va_end (args);
error_flag++;
}
static void
@@ -165,6 +222,12 @@ handle_comment(int type)
seen_slash = 1;
continue;
}
if(seen_star && c == '/') {
if(--level == 0)
return;
seen_star = 0;
continue;
}
if(c == '*') {
if(seen_slash) {
level++;
@@ -184,3 +247,50 @@ handle_comment(int type)
if(c == EOF)
error_message("unterminated comment, possibly started on line %d\n", start_lineno);
}
static char *
handle_string(void)
{
int start_lineno = lineno;
int c;
char buf[1024];
char *p = buf;
int f = 0;
int skip_ws = 0;
while((c = input()) != EOF) {
if(isspace(c) && skip_ws) {
if(c == '\n')
lineno++;
continue;
}
skip_ws = 0;
if(c == '"') {
if(f) {
*p++ = '"';
f = 0;
} else
f = 1;
continue;
}
if(f == 1) {
unput(c);
break;
}
if(c == '\n') {
lineno++;
while(p > buf && isspace((unsigned char)p[-1]))
p--;
skip_ws = 1;
continue;
}
*p++ = c;
}
if(c == EOF)
error_message("unterminated string, possibly started on line %d\n", start_lineno);
*p++ = '\0';
fprintf(stderr, "string -- %s\n", buf);
return estrdup(buf);
}

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).
* All rights reserved.
*
@@ -33,6 +33,19 @@
/* $Id$ */
#include <stdio.h>
#include "symbol.h"
#ifndef __LIBASN1_H__
#define __LIBASN1_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "krb5_asn1.h"
#include "der.h"
#include "asn1_err.h"
#include <parse_units.h>
#endif /* __LIBASN1_H__ */

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).
* All rights reserved.
*
@@ -33,14 +33,32 @@
#include "gen_locl.h"
#include <getarg.h>
#include "lex.h"
RCSID("$Id$");
extern FILE *yyin;
static getarg_strings preserve;
int
preserve_type(const char *p)
{
int i;
for (i = 0; i < preserve.num_strings; i++)
if (strcmp(preserve.strings[i], p) == 0)
return 1;
return 0;
}
int dce_fix;
int rfc1510_bitstring;
int version_flag;
int help_flag;
struct getargs args[] = {
{ "encode-rfc1510-bit-string", 0, arg_flag, &rfc1510_bitstring },
{ "decode-dce-ber", 0, arg_flag, &dce_fix },
{ "preserve-binary", 0, arg_strings, &preserve },
{ "version", 0, arg_flag, &version_flag },
{ "help", 0, arg_flag, &help_flag }
};
@@ -53,12 +71,14 @@ usage(int code)
exit(code);
}
int error_flag;
int
main(int argc, char **argv)
{
int ret;
const char *file;
const char *name = NULL;
char *file;
char *name = NULL;
int optidx = 0;
setprogname(argv[0]);
@@ -79,12 +99,21 @@ main(int argc, char **argv)
yyin = fopen (file, "r");
if (yyin == NULL)
err (1, "open %s", file);
name = argv[optidx + 1];
if (argc == optidx + 1) {
char *p;
name = estrdup(file);
p = strrchr(name, '.');
if (p)
*p = '\0';
} else
name = argv[optidx + 1];
}
init_generate (file, name);
initsym ();
ret = yyparse ();
if(ret != 0 || error_flag != 0)
exit(1);
close_generate ();
return ret;
return 0;
}

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
IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, TypedData
FROM krb5;
IMPORTS SignedData, EnvelopedData FROM CMS;
IMPORTS CertificateSerialNumber, AttributeTypeAndValue, Name FROM X509;
IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, Checksum FROM krb5
IssuerAndSerialNumber, ContentInfo FROM cms
SubjectPublicKeyInfo, AlgorithmIdentifier FROM rfc2459
heim_any FROM heim;
id-pkinit OBJECT IDENTIFIER ::=
{ iso (1) org (3) dod (6) internet (1) security (5)
kerberosv5 (2) pkinit (3) }
-- 3.1
id-pkauthdata OBJECT IDENTIFIER ::= { id-pkinit 1 }
id-pkdhkeydata OBJECT IDENTIFIER ::= { id-pkinit 2 }
id-pkrkeydata OBJECT IDENTIFIER ::= { id-pkinit 3 }
id-pkekuoid OBJECT IDENTIFIER ::= { id-pkinit 4 }
id-pkkdcekuoid OBJECT IDENTIFIER ::= { id-pkinit 5 }
CertPrincipalName ::= SEQUENCE {
name-type[0] INTEGER,
name-string[1] SEQUENCE OF UTF8String
}
pa-pk-as-req INTEGER ::= 16
pa-pk-as-rep INTEGER ::= 17
ad-initial-verified-cas INTEGER ::= 9
-- 3.2.2
td-trusted-certifiers INTEGER ::= 104
td-invalid-certificates INTEGER ::= 105
td-dh-parameters INTEGER ::= 109
DHNonce ::= OCTET STRING
TrustedCertifiers ::= SEQUENCE OF PrincipalName
-- X.500 name encoded as a principal name
-- see Section 3.1
CertificateIndex ::= INTEGER
-- 0 = 1st certificate,
-- (in order of encoding)
-- 1 = 2nd certificate, etc
PA-PK-AS-REP ::= CHOICE {
-- PA TYPE 15
dhSignedData[0] SignedData,
-- Defined in CMS and used only with
-- Diffie-Hellman key exchange (if the
-- client public value was present in the
-- request).
-- This choice MUST be supported
-- by compliant implementations.
encKeyPack[1] EnvelopedData
-- Defined in CMS
-- The temporary key is encrypted
-- using the client public key
-- key
-- SignedReplyKeyPack, encrypted
-- with the temporary key, is also
-- included.
}
KdcDHKeyInfo ::= SEQUENCE {
-- used only when utilizing Diffie-Hellman
nonce[0] INTEGER,
-- binds responce to the request
subjectPublicKey[2] BIT STRING
-- Equals public exponent (g^a mod p)
-- INTEGER encoded as payload of
-- BIT STRING
}
ReplyKeyPack ::= SEQUENCE {
-- not used for Diffie-Hellman
replyKey[0] EncryptionKey,
-- used to encrypt main reply
-- ENCTYPE is at least as strong as
-- ENCTYPE of session key
nonce[1] INTEGER
-- binds response to the request
-- must be same as the nonce
-- passed in the PKAuthenticator
}
-- subjectAltName EXTENSION ::= {
-- SYNTAX GeneralNames
-- IDENTIFIED BY id-ce-subjectAltName
-- }
OtherName ::= SEQUENCE {
type-id OBJECT IDENTIFIER,
value[0] OCTET STRING
-- value[0] EXPLICIT ANY DEFINED BY type-id
}
GeneralName ::= CHOICE {
otherName [0] OtherName,
TrustedCA ::= SEQUENCE {
caName [0] IMPLICIT OCTET STRING,
certificateSerialNumber [1] INTEGER OPTIONAL,
subjectKeyIdentifier [2] OCTET STRING OPTIONAL,
...
}
GeneralNames ::= SEQUENCE -- SIZE(1..MAX)
OF GeneralName
KerberosName ::= SEQUENCE {
realm[0] Realm,
-- as defined in RFC 1510
principalName[1] CertPrincipalName
-- defined above
}
-- krb5 OBJECT IDENTIFIER ::= {
-- iso (1) org (3) dod (6) internet (1) security (5) kerberosv5 (2)
-- }
-- krb5PrincipalName OBJECT IDENTIFIER ::= { krb5 2 }
-- 3.2.1
IssuerAndSerialNumber ::= SEQUENCE {
issuer Name,
serialNumber CertificateSerialNumber
}
TrustedCas ::= CHOICE {
principalName[0] KerberosName,
-- as defined below
caName[1] Name,
-- fully qualified X.500 name
-- as defined by X.509
issuerAndSerial[2] IssuerAndSerialNumber
-- Since a CA may have a number of
-- certificates, only one of which
-- a client trusts
}
PA-PK-AS-REQ ::= SEQUENCE {
-- PA TYPE 14
signedAuthPack[0] SignedData,
-- defined in CMS [11]
-- AuthPack (below) defines the data
-- that is signed
trustedCertifiers[1] SEQUENCE OF TrustedCas OPTIONAL,
-- CAs that the client trusts
kdcCert[2] IssuerAndSerialNumber OPTIONAL,
-- as defined in CMS [11]
-- specifies a particular KDC
-- certificate if the client
-- already has it;
encryptionCert[3] IssuerAndSerialNumber OPTIONAL
-- For example, this may be the
-- client's Diffie-Hellman
-- certificate, or it may be the
-- client's RSA encryption
-- certificate.
signedAuthPack [0] IMPLICIT OCTET STRING,
trustedCertifiers [1] SEQUENCE OF TrustedCA OPTIONAL,
kdcPkId [2] IMPLICIT OCTET STRING OPTIONAL,
...
}
PKAuthenticator ::= SEQUENCE {
kdcName[0] PrincipalName,
kdcRealm[1] Realm,
cusec[2] INTEGER,
-- for replay prevention as in RFC1510
ctime[3] KerberosTime,
-- for replay prevention as in RFC1510
nonce[4] INTEGER
cusec [0] INTEGER -- (0..999999) --,
ctime [1] KerberosTime,
nonce [2] INTEGER (0..4294967295),
paChecksum [3] OCTET STRING,
...
}
-- This is the real definition of AlgorithmIdentifier
-- AlgorithmIdentifier ::= SEQUENCE {
-- algorithm ALGORITHM.&id,
-- parameters ALGORITHM.&Type
-- } -- as specified by the X.509 recommendation[10]
-- But we'll use this one instead:
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters CHOICE {
a INTEGER
}
}
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
-- dhKeyAgreement
subjectPublicKey BIT STRING
-- for DH, equals
-- public exponent (INTEGER encoded
-- as payload of BIT STRING)
} -- as specified by the X.509 recommendation[10]
AuthPack ::= SEQUENCE {
pkAuthenticator[0] PKAuthenticator,
clientPublicValue[1] SubjectPublicKeyInfo OPTIONAL
-- if client is using Diffie-Hellman
-- (ephemeral-ephemeral only)
pkAuthenticator [0] PKAuthenticator,
clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL,
supportedCMSTypes [2] SEQUENCE OF AlgorithmIdentifier OPTIONAL,
clientDHNonce [3] DHNonce OPTIONAL,
...
}
TD-TRUSTED-CERTIFIERS ::= SEQUENCE OF TrustedCA
TD-INVALID-CERTIFICATES ::= SEQUENCE OF OCTET STRING
KRB5PrincipalName ::= SEQUENCE {
realm [0] Realm,
principalName [1] PrincipalName
}
AD-INITIAL-VERIFIED-CAS ::= SEQUENCE OF TrustedCA
DHRepInfo ::= SEQUENCE {
dhSignedData [0] IMPLICIT OCTET STRING,
serverDHNonce [1] DHNonce OPTIONAL
}
PA-PK-AS-REP ::= CHOICE {
dhInfo [0] DHRepInfo,
encKeyPack [1] IMPLICIT OCTET STRING,
...
}
KDCDHKeyInfo ::= SEQUENCE {
subjectPublicKey [0] BIT STRING,
nonce [1] INTEGER (0..4294967295),
dhKeyExpiration [2] KerberosTime OPTIONAL,
...
}
ReplyKeyPack ::= SEQUENCE {
replyKey [0] EncryptionKey,
nonce [1] INTEGER (0..4294967295),
...
}
TD-DH-PARAMETERS ::= SEQUENCE OF AlgorithmIdentifier
-- Windows and pk-init-19 compat glue --
PKAuthenticator-Win2k ::= SEQUENCE {
kdcName [0] PrincipalName,
kdcRealm [1] Realm,
cusec [2] INTEGER (0..4294967295),
ctime [3] KerberosTime,
nonce [4] INTEGER (-2147483648..2147483647)
}
AuthPack-Win2k ::= SEQUENCE {
pkAuthenticator [0] PKAuthenticator-Win2k,
clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL
}
PA-PK-AS-REP-Win2k ::= CHOICE {
dhSignedData [0] IMPLICIT OCTET STRING,
encKeyPack [1] IMPLICIT OCTET STRING
}
KDCDHKeyInfo-Win2k ::= SEQUENCE {
nonce [0] INTEGER (-2147483648..2147483647),
subjectPublicKey [2] BIT STRING
}
TrustedCA-19 ::= CHOICE {
caName [1] heim_any,
issuerAndSerial [2] IssuerAndSerialNumber
}
PA-PK-AS-REQ-19 ::= SEQUENCE { -- PAType 14
signedAuthPack [0] ContentInfo, -- AuthPack
trustedCertifiers [1] SEQUENCE OF TrustedCA-19 OPTIONAL,
kdcCert [2] IssuerAndSerialNumber OPTIONAL,
encryptionCert [3] IssuerAndSerialNumber OPTIONAL,
...
}
PA-PK-AS-REQ-Win2k ::= SEQUENCE {
signed-auth-pack [0] IMPLICIT OCTET STRING,
trusted-certifiers [2] SEQUENCE OF TrustedCA-19 OPTIONAL,
kdc-cert [3] IMPLICIT OCTET STRING OPTIONAL,
encryption-cert [4] IMPLICIT OCTET STRING OPTIONAL
}
PKAuthenticator-19 ::= SEQUENCE {
cusec [0] INTEGER (0..4294967295),
ctime [1] KerberosTime,
nonce [2] INTEGER (0..4294967295),
paChecksum [3] Checksum,
...
}
AuthPack-19 ::= SEQUENCE {
pkAuthenticator [0] PKAuthenticator-19,
clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL
}
PA-PK-AS-REP-19 ::= CHOICE {
dhSignedData [0] ContentInfo,
encKeyPack [1] ContentInfo,
...
}
ReplyKeyPack-19 ::= SEQUENCE {
replyKey [0] EncryptionKey,
nonce [1] INTEGER (0..4294967295),
...
}
END

View File

@@ -1,21 +1,291 @@
-- $Id$ --
-- Definitions from rfc2459/rfc3280
RFC2459 DEFINITIONS ::= BEGIN
AttributeType ::= OBJECT-IDENTIFIER
IMPORTS heim_any FROM heim;
AttributeValue ::= OCTET STRING --ANY DEFINED BY AttributeType
AttributeTypeAndValue ::= SEQUENCE {
type AttributeType,
value AttributeValue
Version ::= INTEGER {
rfc3280_version_1(0),
rfc3280_version_2(1),
rfc3280_version_3(2)
}
RelativeDistinguishedName ::= --SET
SEQUENCE OF AttributeTypeAndValue
id-pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
rsadsi(113549) pkcs(1) 1 }
id-pkcs1-rsaEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 1 }
id-pkcs1-md2WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 2 }
id-pkcs1-md5WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 4 }
id-pkcs1-sha1WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 5 }
id-pkcs-2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
rsadsi(113549) pkcs(1) 2 }
id-pkcs2-md2 OBJECT IDENTIFIER ::= { id-pkcs-2 2 }
id-pkcs2-md4 OBJECT IDENTIFIER ::= { id-pkcs-2 4 }
id-pkcs2-md5 OBJECT IDENTIFIER ::= { id-pkcs-2 5 }
id-pkcs-3 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
rsadsi(113549) pkcs(1) 3 }
id-pkcs3-rc2-cbc OBJECT IDENTIFIER ::= { id-pkcs-3 2 }
id-pkcs3-rc4 OBJECT IDENTIFIER ::= { id-pkcs-3 4 }
id-pkcs3-des-ede3-cbc OBJECT IDENTIFIER ::= { id-pkcs-3 7 }
id-rsadsi-encalg OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
rsadsi(113549) 3 }
id-rsadsi-des-ede3-cbc OBJECT IDENTIFIER ::= { id-rsadsi-encalg 7 }
id-secsig-sha-1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
oiw(14) secsig(3) algorithm(2) 26 }
id-nit-aes-algs OBJECT IDENTIFIER ::= {
joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3)
nistAlgorithm(4) 1 }
id-aes-128-cbc OBJECT IDENTIFIER ::= { id-nit-aes-algs 2 }
id-aes-192-cbc OBJECT IDENTIFIER ::= { id-nit-aes-algs 22 }
id-aes-256-cbc OBJECT IDENTIFIER ::= { id-nit-aes-algs 42 }
id-dhpublicnumber OBJECT IDENTIFIER ::= {
iso(1) member-body(2) us(840) ansi-x942(10046)
number-type(2) 1 }
id-x509-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters heim_any OPTIONAL
}
AttributeType ::= OBJECT IDENTIFIER
AttributeValue ::= heim_any
TeletexStringx ::= [UNIVERSAL 20] IMPLICIT OCTET STRING
DirectoryString ::= CHOICE {
ia5String IA5String,
teletexString TeletexStringx,
printableString PrintableString,
universalString UniversalString,
utf8String UTF8String,
bmpString BMPString
}
Attribute ::= SEQUENCE {
type AttributeType,
value AttributeValue
}
AttributeTypeAndValue ::= SEQUENCE {
type AttributeType,
value DirectoryString
}
RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
Name ::= CHOICE { -- RFC2459
x RDNSequence
Name ::= CHOICE {
rdnSequence RDNSequence
}
CertificateSerialNumber ::= INTEGER
Time ::= CHOICE {
utcTime UTCTime,
generalTime GeneralizedTime
}
Validity ::= SEQUENCE {
notBefore Time,
notAfter Time
}
UniqueIdentifier ::= BIT STRING
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING
}
Extension ::= SEQUENCE {
extnID OBJECT IDENTIFIER,
critical BOOLEAN OPTIONAL, -- DEFAULT FALSE XXX
extnValue OCTET STRING
}
Extensions ::= SEQUENCE OF Extension -- SIZE (1..MAX)
TBSCertificate ::= SEQUENCE {
version [0] Version OPTIONAL, -- EXPLICIT nnn DEFAULT 1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version shall be v2 or v3
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version shall be v2 or v3
extensions [3] EXPLICIT Extensions OPTIONAL
-- If present, version shall be v3
}
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING
}
Certificates ::= SEQUENCE OF Certificate
ValidationParms ::= SEQUENCE {
seed BIT STRING,
pgenCounter INTEGER
}
DomainParameters ::= SEQUENCE {
p INTEGER, -- odd prime, p=jq +1
g INTEGER, -- generator, g
q INTEGER, -- factor of p-1
j INTEGER OPTIONAL, -- subgroup factor
validationParms ValidationParms OPTIONAL -- ValidationParms
}
OtherName ::= SEQUENCE {
type-id OBJECT IDENTIFIER,
value [0] EXPLICIT heim_any
}
GeneralName ::= CHOICE {
otherName [0] OtherName,
rfc822Name [1] IA5String,
dNSName [2] IA5String,
-- x400Address [3] ORAddress,--
directoryName [4] Name,
-- ediPartyName [5] EDIPartyName, --
uniformResourceIdentifier [6] IA5String,
iPAddress [7] OCTET STRING,
registeredID [8] OBJECT IDENTIFIER
}
GeneralNames ::= SEQUENCE -- SIZE (1..MAX) -- OF GeneralName
id-x509-ce-keyUsage OBJECT IDENTIFIER ::= { id-x509-ce 15 }
KeyUsage ::= BIT STRING {
digitalSignature (0),
nonRepudiation (1),
keyEncipherment (2),
dataEncipherment (3),
keyAgreement (4),
keyCertSign (5),
cRLSign (6),
encipherOnly (7),
decipherOnly (8)
}
id-x509-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-x509-ce 35 }
KeyIdentifier ::= OCTET STRING
AuthorityKeyIdentifier ::= SEQUENCE {
keyIdentifier [0] IMPLICIT OCTET STRING OPTIONAL,
authorityCertIssuer [1] IMPLICIT heim_any OPTIONAL,
authorityCertSerialNumber [2] IMPLICIT INTEGER OPTIONAL
}
id-x509-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-x509-ce 14 }
SubjectKeyIdentifier ::= KeyIdentifier
id-x509-ce-basicConstraints OBJECT IDENTIFIER ::= { id-x509-ce 19 }
BasicConstraints ::= SEQUENCE {
cA BOOLEAN OPTIONAL -- DEFAULT FALSE --,
pathLenConstraint INTEGER (0..4294967295) OPTIONAL
}
id-x509-ce-nameConstraints OBJECT IDENTIFIER ::= { id-x509-ce 30 }
BaseDistance ::= INTEGER -- (0..MAX) --
GeneralSubtree ::= SEQUENCE {
base GeneralName,
minimum [0] BaseDistance OPTIONAL -- DEFAULT 0 --,
maximum [1] BaseDistance OPTIONAL
}
GeneralSubtrees ::= SEQUENCE -- SIZE (1..MAX) -- OF GeneralSubtree
NameConstraints ::= SEQUENCE {
permittedSubtrees [0] GeneralSubtrees OPTIONAL,
excludedSubtrees [1] GeneralSubtrees OPTIONAL
}
id-x509-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= { id-x509-ce 16 }
id-x509-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-x509-ce 32 }
id-x509-ce-policyMappings OBJECT IDENTIFIER ::= { id-x509-ce 33 }
id-x509-ce-subjectAltName OBJECT IDENTIFIER ::= { id-x509-ce 17 }
id-x509-ce-issuerAltName OBJECT IDENTIFIER ::= { id-x509-ce 18 }
id-x509-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-x509-ce 9 }
id-x509-ce-policyConstraints OBJECT IDENTIFIER ::= { id-x509-ce 36 }
id-x509-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-x509-ce 37}
id-x509-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-x509-ce 31 }
id-x509-ce-cRLNumber OBJECT IDENTIFIER ::= { id-x509-ce 20 }
id-x509-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-x509-ce 27 }
id-x509-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-x509-ce 28 }
id-x509-ce-cRLReasons OBJECT IDENTIFIER ::= { id-x509-ce 21 }
id-x509-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-x509-ce 23 }
id-x509-ce-invalidityDate OBJECT IDENTIFIER ::= { id-x509-ce 24 }
id-x509-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-x509-ce 29 }
id-x509-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-x509-ce 54 }
id-x509-ce-freshestCRL OBJECT IDENTIFIER ::= { id-x509-ce 46 }
-- rfc3279
DSASigValue ::= SEQUENCE {
r INTEGER,
s INTEGER
}
DSAPublicKey ::= INTEGER
DSAParams ::= SEQUENCE {
p INTEGER,
q INTEGER,
g INTEGER
}
-- really pkcs1
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
DigestInfo ::= SEQUENCE {
digestAlgorithm AlgorithmIdentifier,
digest OCTET STRING
}
-- some ms ext
-- szOID_ENROLL_CERTTYPE_EXTENSION "1.3.6.1.4.1.311.20.2" is Encoded as a
-- UNICODESTRING (0x1E tag)
-- szOID_CERTIFICATE_TEMPLATE "1.3.6.1.4.1.311.21.7" is Encoded as:
-- TemplateVersion ::= INTEGER (0..4294967295)
-- CertificateTemplate ::= SEQUENCE {
-- templateID OBJECT IDENTIFIER,
-- templateMajorVersion TemplateVersion,
-- templateMinorVersion TemplateVersion OPTIONAL
-- }
END

View File

@@ -168,25 +168,25 @@ Request ::= [ APPLICATION 0 ] SEQUENCE {
languages[2] SEQUENCE OF Language-Tag OPTIONAL,
targ-name[3] PrincipalName OPTIONAL,
targ-realm[4] Realm OPTIONAL,
-- operation[5] Op-Req,
operation[5] Op-Req,
...
}
Responce ::= [ APPLICATION 1 ] SEQUENCE {
Response ::= [ APPLICATION 1 ] SEQUENCE {
pvno-major[0] INTEGER DEFAULT 2,
pvno-minor[1] INTEGER DEFAULT 0,
language[2] Language-Tag DEFAULT "i-default",
-- result[3] Op-rep OPTIONAL,
result[3] Op-rep OPTIONAL,
...
}
Error-Responce ::= [ APPLICATION 2 ] SEQUENCE {
Error-Response ::= [ APPLICATION 2 ] SEQUENCE {
pvno-major[0] INTEGER DEFAULT 2,
pvno-minor[1] INTEGER DEFAULT 0,
language[2] Language-Tag DEFAULT "i-default",
error-code[3] ProtocolErrorCode,
help-text[4] UTF8String OPTIONAL,
-- op-error[5] Op-error OP-ERROR,
op-error[5] Op-error OP-ERROR,
...
}

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).
* All rights reserved.
*
@@ -32,59 +32,79 @@
*/
#include "gen_locl.h"
#include "lex.h"
RCSID("$Id$");
static Hashtab *htab;
static int
cmp (void *a, void *b)
cmp(void *a, void *b)
{
Symbol *s1 = (Symbol *)a;
Symbol *s2 = (Symbol *)b;
Symbol *s1 = (Symbol *) a;
Symbol *s2 = (Symbol *) b;
return strcmp (s1->name, s2->name);
return strcmp(s1->name, s2->name);
}
static unsigned
hash (void *a)
hash(void *a)
{
Symbol *s = (Symbol *)a;
Symbol *s = (Symbol *) a;
return hashjpw (s->name);
return hashjpw(s->name);
}
void
initsym (void)
initsym(void)
{
htab = hashtabnew (101, cmp, hash);
htab = hashtabnew(101, cmp, hash);
}
void
output_name (char *s)
output_name(char *s)
{
char *p;
char *p;
for (p = s; *p; ++p)
if (*p == '-')
*p = '_';
for (p = s; *p; ++p)
if (*p == '-')
*p = '_';
}
Symbol*
addsym (char *name)
Symbol *
addsym(char *name)
{
Symbol key, *s;
Symbol key, *s;
key.name = name;
s = (Symbol *)hashtabsearch (htab, (void *)&key);
if (s == NULL) {
s = (Symbol *)malloc (sizeof (*s));
s->name = name;
s->gen_name = strdup(name);
output_name (s->gen_name);
s->stype = SUndefined;
hashtabadd (htab, s);
}
return s;
key.name = name;
s = (Symbol *) hashtabsearch(htab, (void *) &key);
if (s == NULL) {
s = (Symbol *) emalloc(sizeof(*s));
s->name = name;
s->gen_name = estrdup(name);
output_name(s->gen_name);
s->stype = SUndefined;
hashtabadd(htab, s);
}
return s;
}
static int
checkfunc(void *ptr, void *arg)
{
Symbol *s = ptr;
if (s->stype == SUndefined) {
error_message("%s is still undefined\n", s->name);
*(int *) arg = 1;
}
return 0;
}
int
checkundefined(void)
{
int f = 0;
hashtabforeach(htab, checkfunc, &f);
return f;
}

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

30
lib/asn1/test.asn1 Normal file
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
CertificateSerialNumber ::= INTEGER -- X.509 '97
IMPORTS heim_any FROM heim;
AttributeType ::= OBJECT-IDENTIFIER
Version ::= INTEGER -- { v1(0), v2(1), v3(2) } --
AttributeValue ::= OCTET STRING --ANY DEFINED BY AttributeType
AlgorithmIdentifier ::= OBJECT IDENTIFIER
AttributeTypeAndValue ::= SEQUENCE {
type AttributeType,
value AttributeValue
AttributeType ::= OBJECT IDENTIFIER
AttributeValue ::= heim_any
Attribute ::= SEQUENCE {
type AttributeType,
value AttributeValue
}
RelativeDistinguishedName ::= --SET
SEQUENCE OF AttributeTypeAndValue
RelativeDistinguishedName ::= SET OF Attribute
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
Name ::= CHOICE { -- RFC2459
x RDNSequence
DistinguishedName ::= RDNSequence
Name ::= CHOICE { -- only one possibility for now --
rdnSequence RDNSequence
}
CertificateSerialNumber ::= INTEGER
Time ::= CHOICE {
utcTime UTCTime,
generalTime GeneralizedTime
}
Validity ::= SEQUENCE {
notBefore Time,
notAfter Time
}
UniqueIdentifier ::= BIT STRING
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING
}
Extension ::= SEQUENCE {
extnID OBJECT IDENTIFIER,
critical BOOLEAN DEFAULT FALSE,
extnValue OCTET STRING
}
Extensions ::= SEQUENCE OF Extension -- SIZE (1..MAX)
TBSCertificate ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT 1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version shall be v2 or v3
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version shall be v2 or v3
extensions [3] EXPLICIT Extensions OPTIONAL
-- If present, version shall be v3
}
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING
}
END