1. 13 8月, 2015 3 次提交
    • D
      PKCS#7: Support CMS messages also [RFC5652] · 60d65cac
      David Howells 提交于
      Since CMS is an evolution of PKCS#7, with much of the ASN.1 being
      compatible, add support for CMS signed-data messages also [RFC5652 sec 5].
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-By: NDavid Woodhouse <David.Woodhouse@intel.com>
      60d65cac
    • D
      X.509: Change recorded SKID & AKID to not include Subject or Issuer · a4c6e57f
      David Howells 提交于
      The key identifiers fabricated from an X.509 certificate are currently:
      
       (A) Concatenation of serial number and issuer
      
       (B) Concatenation of subject and subjectKeyID (SKID)
      
      When verifying one X.509 certificate with another, the AKID in the target
      can be used to match the authoritative certificate.  The AKID can specify
      the match in one or both of two ways:
      
       (1) Compare authorityCertSerialNumber and authorityCertIssuer from the AKID
           to identifier (A) above.
      
       (2) Compare keyIdentifier from the AKID plus the issuer from the target
           certificate to identifier (B) above.
      
      When verifying a PKCS#7 message, the only available comparison is between
      the IssuerAndSerialNumber field and identifier (A) above.
      
      However, a subsequent patch adds CMS support.  Whilst CMS still supports a
      match on IssuerAndSerialNumber as for PKCS#7, it also supports an
      alternative - which is the SubjectKeyIdentifier field.  This is used to
      match to an X.509 certificate on the SKID alone.  No subject information is
      available to be used.
      
      To this end change the fabrication of (B) above to be from the X.509 SKID
      alone.  The AKID in keyIdentifier form then only matches on that and does
      not include the issuer.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-By: NDavid Woodhouse <David.Woodhouse@intel.com>
      a4c6e57f
    • D
      PKCS#7: Check content type and versions · 2c7fd367
      David Howells 提交于
      We only support PKCS#7 signed-data [RFC2315 sec 9] content at the top level,
      so reject anything else.  Further, check that the version numbers in
      SignedData and SignerInfo are 1 in both cases.
      
      Note that we don't restrict the inner content type.  In the PKCS#7 code we
      don't parse the data attached there, but merely verify the signature over
      it.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-By: NDavid Woodhouse <David.Woodhouse@intel.com>
      2c7fd367
  2. 07 8月, 2015 18 次提交
  3. 05 8月, 2015 4 次提交
    • D
      ASN.1: Handle 'ANY OPTIONAL' in grammar · 233ce79d
      David Howells 提交于
      An ANY object in an ASN.1 grammar that is marked OPTIONAL should be skipped
      if there is no more data to be had.
      
      This can be tested by editing X.509 certificates or PKCS#7 messages to
      remove the NULL from subobjects that look like the following:
      
      	SEQUENCE {
      	  OBJECT(2a864886f70d01010b);
      	  NULL();
      	}
      
      This is an algorithm identifier plus an optional parameter.
      
      The modified DER can be passed to one of:
      
      	keyctl padd asymmetric "" @s </tmp/modified.x509
      	keyctl padd pkcs7_test foo @s </tmp/modified.pkcs7
      
      It should work okay with the patch and produce EBADMSG without.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Tested-by: NMarcel Holtmann <marcel@holtmann.org>
      Reviewed-by: NDavid Woodhouse <David.Woodhouse@intel.com>
      233ce79d
    • D
      ASN.1: Fix non-match detection failure on data overrun · 0d62e9dd
      David Howells 提交于
      If the ASN.1 decoder is asked to parse a sequence of objects, non-optional
      matches get skipped if there's no more data to be had rather than a
      data-overrun error being reported.
      
      This is due to the code segment that decides whether to skip optional
      matches (ie. matches that could get ignored because an element is marked
      OPTIONAL in the grammar) due to a lack of data also skips non-optional
      elements if the data pointer has reached the end of the buffer.
      
      This can be tested with the data decoder for the new RSA akcipher algorithm
      that takes three non-optional integers.  Currently, it skips the last
      integer if there is insufficient data.
      
      Without the fix, #defining DEBUG in asn1_decoder.c will show something
      like:
      
      	next_op: pc=0/13 dp=0/270 C=0 J=0
      	- match? 30 30 00
      	- TAG: 30 266 CONS
      	next_op: pc=2/13 dp=4/270 C=1 J=0
      	- match? 02 02 00
      	- TAG: 02 257
      	- LEAF: 257
      	next_op: pc=5/13 dp=265/270 C=1 J=0
      	- match? 02 02 00
      	- TAG: 02 3
      	- LEAF: 3
      	next_op: pc=8/13 dp=270/270 C=1 J=0
      	next_op: pc=11/13 dp=270/270 C=1 J=0
      	- end cons t=4 dp=270 l=270/270
      
      The next_op line for pc=8/13 should be followed by a match line.
      
      This is not exploitable for X.509 certificates by means of shortening the
      message and fixing up the ASN.1 CONS tags because:
      
       (1) The relevant records being built up are cleared before use.
      
       (2) If the message is shortened sufficiently to remove the public key, the
           ASN.1 parse of the RSA key will fail quickly due to a lack of data.
      
       (3) Extracted signature data is either turned into MPIs (which cope with a
           0 length) or is simpler integers specifying algoritms and suchlike
           (which can validly be 0); and
      
       (4) The AKID and SKID extensions are optional and their removal is handled
           without risking passing a NULL to asymmetric_key_generate_id().
      
       (5) If the certificate is truncated sufficiently to remove the subject,
           issuer or serialNumber then the ASN.1 decoder will fail with a 'Cons
           stack underflow' return.
      
      This is not exploitable for PKCS#7 messages by means of removal of elements
      from such a message from the tail end of a sequence:
      
       (1) Any shortened X.509 certs embedded in the PKCS#7 message are survivable
           as detailed above.
      
       (2) The message digest content isn't used if it shows a NULL pointer,
           similarly, the authattrs aren't used if that shows a NULL pointer.
      
       (3) A missing signature results in a NULL MPI - which the MPI routines deal
           with.
      
       (4) If data is NULL, it is expected that the message has detached content and
           that is handled appropriately.
      
       (5) If the serialNumber is excised, the unconditional action associated
           with it will pick up the containing SEQUENCE instead, so no NULL
           pointer will be seen here.
      
           If both the issuer and the serialNumber are excised, the ASN.1 decode
           will fail with an 'Unexpected tag' return.
      
           In either case, there's no way to get to asymmetric_key_generate_id()
           with a NULL pointer.
      
       (6) Other fields are decoded to simple integers.  Shortening the message
           to omit an algorithm ID field will cause checks on this to fail early
           in the verification process.
      
      
      This can also be tested by snipping objects off of the end of the ASN.1 stream
      such that mandatory tags are removed - or even from the end of internal
      SEQUENCEs.  If any mandatory tag is missing, the error EBADMSG *should* be
      produced.  Without this patch ERANGE or ENOPKG might be produced or the parse
      may apparently succeed, perhaps with ENOKEY or EKEYREJECTED being produced
      later, depending on what gets snipped.
      
      Just snipping off the final BIT_STRING or OCTET_STRING from either sample
      should be a start since both are mandatory and neither will cause an EBADMSG
      without the patches
      Reported-by: NMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Tested-by: NMarcel Holtmann <marcel@holtmann.org>
      Reviewed-by: NDavid Woodhouse <David.Woodhouse@intel.com>
      0d62e9dd
    • D
      ASN.1: Fix actions on CHOICE elements with IMPLICIT tags · 3f3af97d
      David Howells 提交于
      In an ASN.1 description where there is a CHOICE construct that contains
      elements with IMPLICIT tags that refer to constructed types, actions to be
      taken on those elements should be conditional on the corresponding element
      actually being matched.  Currently, however, such actions are performed
      unconditionally in the middle of processing the CHOICE.
      
      For example, look at elements 'b' and 'e' here:
      
      	A ::= SEQUENCE {
      			CHOICE {
      			b [0] IMPLICIT B ({ do_XXXXXXXXXXXX_b }),
      			c [1] EXPLICIT C ({ do_XXXXXXXXXXXX_c }),
      			d [2] EXPLICIT B ({ do_XXXXXXXXXXXX_d }),
      			e [3] IMPLICIT C ({ do_XXXXXXXXXXXX_e }),
      			f [4] IMPLICIT INTEGER ({ do_XXXXXXXXXXXX_f })
      			}
      		} ({ do_XXXXXXXXXXXX_A })
      
      	B ::= SET OF OBJECT IDENTIFIER ({ do_XXXXXXXXXXXX_oid })
      
      	C ::= SET OF INTEGER ({ do_XXXXXXXXXXXX_int })
      
      They each have an action (do_XXXXXXXXXXXX_b and do_XXXXXXXXXXXX_e) that
      should only be processed if that element is matched.
      
      The problem is that there's no easy place to hang the action off in the
      subclause (type B for element 'b' and type C for element 'e') because
      subclause opcode sequences can be shared.
      
      To fix this, introduce a conditional action opcode(ASN1_OP_MAYBE_ACT) that
      the decoder only processes if the preceding match was successful.  This can
      be seen in an excerpt from the output of the fixed ASN.1 compiler for the
      above ASN.1 description:
      
      	[  13] =  ASN1_OP_COND_MATCH_JUMP_OR_SKIP,		// e
      	[  14] =  _tagn(CONT, CONS,  3),
      	[  15] =  _jump_target(45),		// --> C
      	[  16] =  ASN1_OP_MAYBE_ACT,
      	[  17] =  _action(ACT_do_XXXXXXXXXXXX_e),
      
      In this, if the op at [13] is matched (ie. element 'e' above) then the
      action at [16] will be performed.  However, if the op at [13] doesn't match
      or is skipped because it is conditional and some previous op matched, then
      the action at [16] will be ignored.
      
      Note that to make this work in the decoder, the ASN1_OP_RETURN op must set
      the flag to indicate that a match happened.  This is necessary because the
      _jump_target() seen above introduces a subclause (in this case an object of
      type 'C') which is likely to alter the flag.  Setting the flag here is okay
      because to process a subclause, a match must have happened and caused a
      jump.
      
      This cannot be tested with the code as it stands, but rather affects future
      code.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-by: NDavid Woodhouse <David.Woodhouse@intel.com>
      3f3af97d
    • D
      ASN.1: Fix handling of CHOICE in ASN.1 compiler · 8d9b21dc
      David Howells 提交于
      Fix the handling of CHOICE types in the ASN.1 compiler to make SEQUENCE and
      SET elements in a CHOICE be correctly rendered as skippable and conditional
      as appropriate.
      
      For example, in the following ASN.1:
      
      	Foo ::= SEQUENCE { w1 INTEGER, w2 Bar, w3 OBJECT IDENTIFIER }
      	Bar ::= CHOICE {
      		x1 Seq1,
      		x2 [0] IMPLICIT OCTET STRING,
      		x3 Seq2,
      		x4 SET OF INTEGER
      	}
      	Seq1 ::= SEQUENCE { y1 INTEGER, y2 INTEGER, y3 INTEGER }
      	Seq2 ::= SEQUENCE { z1 BOOLEAN, z2 BOOLEAN, z3 BOOLEAN }
      
      the output in foo.c generated by:
      
      	./scripts/asn1_compiler foo.asn1 foo.c foo.h
      
      included:
      
      	// Bar
      	// Seq1
      	[   4] =  ASN1_OP_MATCH,
      	[   5] =  _tag(UNIV, CONS, SEQ),
      	...
      	[  13] =  ASN1_OP_COND_MATCH_OR_SKIP,		// x2
      	[  14] =  _tagn(CONT, PRIM,  0),
      	// Seq2
      	[  15] =  ASN1_OP_MATCH,
      	[  16] =  _tag(UNIV, CONS, SEQ),
      	...
      	[  24] =  ASN1_OP_COND_MATCH_JUMP_OR_SKIP,		// x4
      	[  25] =  _tag(UNIV, CONS, SET),
      	...
      	[  27] =  ASN1_OP_COND_FAIL,
      
      as a result of the CHOICE - but this is wrong on lines 4 and 15 because
      both of these should be skippable (one and only one of the four can be
      picked) and the one on line 15 should also be conditional so that it is
      ignored if anything before it matches.
      
      After the patch, it looks like:
      
      	// Bar
      	// Seq1
      	[   4] =  ASN1_OP_MATCH_JUMP_OR_SKIP,		// x1
      	[   5] =  _tag(UNIV, CONS, SEQ),
      	...
      	[   7] =  ASN1_OP_COND_MATCH_OR_SKIP,		// x2
      	[   8] =  _tagn(CONT, PRIM,  0),
      	// Seq2
      	[   9] =  ASN1_OP_COND_MATCH_JUMP_OR_SKIP,		// x3
      	[  10] =  _tag(UNIV, CONS, SEQ),
      	...
      	[  12] =  ASN1_OP_COND_MATCH_JUMP_OR_SKIP,		// x4
      	[  13] =  _tag(UNIV, CONS, SET),
      	...
      	[  15] =  ASN1_OP_COND_FAIL,
      
      where all four options are skippable and the second, third and fourth are
      all conditional, as is the backstop at the end.
      
      This hasn't been a problem so far because in the ASN.1 specs we have are
      either using primitives or are using SET OF and SEQUENCE OF which are
      handled correctly.
      
      Whilst we're at it, also make sure that element labels get included in
      comments in the output for elements that have complex types.
      
      This cannot be tested with the code as it stands, but rather affects future
      code.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-By: NDavid Woodhouse <David.Woodhouse@intel.com>
      8d9b21dc
  4. 28 7月, 2015 1 次提交
  5. 20 7月, 2015 6 次提交
  6. 19 7月, 2015 8 次提交