Hello,
While debugging our ASN.1/PER encoder, I noticed a problem with the way ICV is calculated in H.225.0.
Briefly, the PER encodings change when a SEQUENCE type is further extended, even if the new extension additions are not included in the SEQUENCE value.
The issue prevents interoperability between software using H.225.0 version 2 and software using any version, it should be solved before any version 2 devices are released.
Pekka Pessi
h2250-integrityCheckValue-problem.txt Pekka Pessi pessi@research.nokia.com $Revision: 1.1 $ Nokia Research Center June 1998
Comments on H.225.0 (1998): Problems When Calculating integrityCheckValue
The current H.225.0 algorithm for calculating the ICV does not work well with the PER extension mechanism. In order to interwork, each H.323 device needs a separate PER encoding function for each version of H.225.0 ASN.1 definitions.
Algorithm for Calculating integityCheckValue
According to the H.225.0 v2, integrityCheckValue is defined and calculated as follows:
ICV ::= SEQUENCE { algorithmOID OBJECT IDENTIFIER, -- the algorithm used to compute the signature icv BIT STRING -- the computed cryptographic integrity check -- value or signature }
integrityCheckValue - provides improved message integrity/message authentication of the RAS messages. The cryptographically based integrity check value is computed by the sender applying a negotiated integrity algorithm and the secret key upon the entire message. Prior to integrityCheckValue computation this field shall be ignored and shall be empty. After computation, the sender puts the computed integrity check value in the integrityCheckValue field and transmits the message.
The above algorithm (AFAIK I have understood it correctly) assumes that the sender and receiver can encode the PDU exactly in the same way. It is a reasonable assumption, as PER produces only one possible (canonical) encoding for given PDU. However, there is a serious problem: the canonical representation changes if the ASN.1 SEQUENCE type is extended later.
PER Encoding of an Extended ASN.1 SEQUENCE
In the PER encoding of extensions to SEQUENCE types, the encoder first encodes the number of extensions as a normally small non-negative integer, then a bit field with one bit for each extension followed by the extensions itself (bit is one if the extension is present, zero if not). The encoding of each extension is preceded by the length of their encoding in octets.
Now, if the sender A uses following ASN.1 definition for a SEQUENCE
Foo ::= SEQUENCE { bar INTEGER (0..127), ..., baz INTEGER (0..255) OPTIONAL, integrityCheckValue ICV OPTIONAL }
When encoding this, the length of extension bitfield is 2. However, recipient B is using extended version of Foo like this:
Foo ::= SEQUENCE { bar INTEGER (0..127), ..., baz INTEGER (0..255) OPTIONAL, integrityCheckValue ICV OPTIONAL, importantExtension SomeType OPTIONAL }
B decodes the Foo, removes ICV and encodes the packet again. In the resulting encoding, the length of extension bitfield is 3, and the ICV that B regenerates is different that A generated and sent to B. B is not able to interwork with systems using earlier version of the ASN.1 spec.
ASN.1 Compilers Don't Grok Unknown Extensions
There are also problems because the way some ASN.1 compilers behave. Using our previous example, when A receives Foo with the importantExtension field from B, A has somehow to include the value when it is re-encoding Foo in order to calculate the ICV. However, it may be very hard to present an value of an unknown extension to the ASN.1 encoding functions. As a possible solution the ICV calculation could be included in the ASN.1 decoding process.
Problems with Non-OPTIONAL Extensions
Another problem with some ASN.1 compilers is inclusion of non-OPTIONAL extensions. Let us assume that software C uses following ASN.1 definition for Foo:
Foo ::= SEQUENCE { bar INTEGER (0..127), ..., baz INTEGER (0..255) OPTIONAL, integrityCheckValue ICV OPTIONAL, importantExtension SomeType OPTIONAL, criticalExtension OtherType }
There are two kinds of problems with an extension like criticalExtension. First, the encoder may try to ensure that all encoded PDUs conform to the specification and signal an error when a PDU without criticalExtension is encoded. Another problem is that the intermediate representation produced by the ASN.1 compiler may not provide means for application to express that criticalExtension is not present. (In other words, the produced structure usually contains a flag telling whether an optional field is present or not. Such flags are not included when the field is not optional.)
The presense or absence of the OPTIONAL flag in an extension does not change the PER encoding of the SEQUENCE. In order to avoid previously mentioned problems, application may use a version of ASN.1 notation that has extra OPTIONAL keyword after each extension.
Solution 1: Clarification to the PER Encoding Process
The text in PER document (X.691, 1994) is somewhat ambiguous how many bits should be included in the extension present bitfield of SEQUENCE. To quote verbatim: "Let the number of extension additions in the type being encoded be "n", then a bit-field with "n" bits shall be produced for addition to the field-list." (Is the "type being encoded" the abstract syntax or an actual value like { bar 1, baz 2 }?) However, the 0 bits at the end of extension present bitfield can be left out without changing the resulting semantics: the corresponding extensions are not present. As a result, the PER encoding does not change after a new extension is added to the ASN.1 specification.
This solution, while leaving H.225.0 v2 protocol as it is, requires however changes to some existing ASN.1 compilers, and in a pessimal case, to the X.691 standard text, too.
Solution 2: Hack
The receiving application does not decode and the re-encode the PDU, but rather removes the ICV from the encoded PDU. In practice, this requires that application can identify PER-encoded fields within the PDU and it can regenerate them, i.e. it has effectively the same functionality as a PER encoder/decoder.
Solution 3: Calculating ICV Differently
The following algorithm for generating and checking the ICV makes it possible to avoid all the previously mentioned problems. The problems are avoided by breaking the protocol layering, the application changes directly the PER-encoded PDU:
integrityCheckValue - provides improved message integrity/message authentication of the RAS messages. The cryptographically based integrity check value is computed by the sender applying a negotiated integrity algorithm and the secret key upon the entire message. Prior to integrityCheckValue computation an ICV with a previously agreed magic value (or key when using MDC) will be inserted to this field. The magic value will contain same algorithmOID and exactly as many bits in the icv BIT STRING as the computed value. After computation, the sender replaces the magic value with the computed integrity check value and transmits message. The receiver decodes message, replaces the received integrity value with the magic value, calculates the ICV and compares it with the received value.
NOTE: The sender or receiver can encode the ICV separately and replace it directly within the encoded PDU, when the magic ICV and computed ICV have exactly the same length. When replacing ICV value within an encoded PDU, re-encoding the whole PDU can be avoided.
NOTE: The above algorithm does not require directly changing the PER-encoded PDU. Like the current algorithm, ICV can be replaced with a new value above presentation layer then PDU will be re-encoded. It makes it easy, however: as the magic value is a very unique octet-aligned bit pattern (random data of 64 bits or more, probably), it should be easy to spot and replace it from the encoded PDU.
NOTE: It is not advisable to use magic value as the key to MAC algorithm.
Example code:
int icv_replace( u_char *msg, size_t len, u_char const *icv, u_char const *magic, size_t ilen) { u_char *m, *mim; size_t i, j, ilen_in_octets, ilen_in_full_octets;
ilen_in_octets = (ilen + 7) >> 3; ilen_in_full_octets = ilen >> 3;
/* find magic value from message */ for (m = msg, mim = NULL; m - msg < len - ilen_in_octets; m++) { /* NOTE: the magic value/icv may not be integral number of octets */ for (i = 0; i < ilen_in_full_octets; i++) { if (m[i] != magic[i]) break; } if (i == ilen_in_full_octets) { if (mim) return -2; /* failure: two or more magic values found */ mim = m; } }
if (mim == NULL) { return -1; /* failure: no magic value found */
/* replace magic value with icv */ for (i = 0; i < ilen_in_octets; i++) { mim[i] ^= magic[i] ^ icv[i]; }
return 0; /* success */ }
Solution 4:
Fourth alternative is to treat encoded RasMessage as octet string. IVC can be calculated over that octet string and appended to the PDU on separate layer. E.g., RAS PDU could be defined as follows:
RasMessage ::= CHOICE { --8<----8<----8<----8<----8<----8<----8<----8<----8<----8<-- -- all previous RasMessage CHOICEs are here --8<----8<----8<----8<----8<----8<----8<----8<----8<----8<-- authenticatedRasMessage SEQUENCE { plainRasMessage OCTET STRING, ivc IVC, ... } }
Pekka Pessi wrote:
The issue prevents interoperability between software using H.225.0 version 2 and software using any version, it should be solved before any version 2 devices are released.
I have raised the issue of compatibility between versions here before, but nobody except me seems to think that it will be a problem. Time will tell.
However, there is a serious problem: the canonical representation changes if the ASN.1 SEQUENCE type is extended later.
Correct, a SEQUENCE type must be defined as extensible starting with the first version in which it is defined if it is felt that it may need to be extended in the future. Once a SEQUENCE type is defined to be NOT extensible (there is no extension marker present), it cannot later be extended without changing the encoding. For example, the ICV type can never be extended.
PER Encoding of an Extended ASN.1 SEQUENCE
In the PER encoding of extensions to SEQUENCE types, the encoder first encodes the number of extensions as a normally small non-negative integer, then a bit field with one bit for each extension followed by the extensions itself (bit is one if the extension is present, zero if not). The encoding of each extension is preceded by the length of their encoding in octets.
Now, if the sender A uses following ASN.1 definition for a SEQUENCE
Foo ::= SEQUENCE { bar INTEGER (0..127), ..., baz INTEGER (0..255) OPTIONAL, integrityCheckValue ICV OPTIONAL }
When encoding this, the length of extension bitfield is 2. However, recipient B is using extended version of Foo like this:
Foo ::= SEQUENCE { bar INTEGER (0..127), ..., baz INTEGER (0..255) OPTIONAL, integrityCheckValue ICV OPTIONAL, importantExtension SomeType OPTIONAL }
B decodes the Foo, removes ICV and encodes the packet again. In the resulting encoding, the length of extension bitfield is 3, and the ICV that B regenerates is different that A generated and sent to B. B is not able to interwork with systems using earlier version of the ASN.1 spec.
Why not? This is precisely what the H.225.0 and H.245 protocolIdentifier is for--to indicate which version of the Recommendation the endpoint supports. An endpoint must know what protocol versions the remote terminal supports. For example, if an H.225.0v3 endpoint communicates with a v2 endpoint, it knows that the v2 endpoint will not recognize any of the extensions added since v2 and shall not therefore depend on any v3 behavior on the part of the v2 endpoint. Likewise, the v2 endpoint must be able to treat all v2 and subsequent endpoints as a v2 endpoint. Basically, an extension cannot be added to the ASN.1 syntax of a Recomendation that changes the semantics of the fields defined in the previous version of the Recommendation. If this is done, we will have serious interoperability problems.
ASN.1 Compilers Don't Grok Unknown Extensions
There are also problems because the way some ASN.1 compilers behave. Using our previous example, when A receives Foo with the importantExtension field from B, A has somehow to include the value when it is re-encoding Foo in order to calculate the ICV.
I can't think of a situation where a terminal would ever have to re-encode. Are you referring to a GK or GW?
However, it may be very hard to present an value of an unknown extension to the ASN.1 encoding functions.
We use our own ASN.1 codec, so this isn't a problem for us.
Problems with Non-OPTIONAL Extensions
Another problem with some ASN.1 compilers is inclusion of non-OPTIONAL extensions. Let us assume that software C uses following ASN.1 definition for Foo:
Foo ::= SEQUENCE { bar INTEGER (0..127), ..., baz INTEGER (0..255) OPTIONAL, integrityCheckValue ICV OPTIONAL, importantExtension SomeType OPTIONAL, criticalExtension OtherType }
There are two kinds of problems with an extension like criticalExtension. First, the encoder may try to ensure that all encoded PDUs conform to the specification and signal an error when a PDU without criticalExtension is encoded.
IMO, this is correct behavior.
Another problem is that the intermediate representation produced by the ASN.1 compiler may not provide means for application to express that criticalExtension is not present. (In other words, the produced structure usually contains a flag telling whether an optional field is present or not. Such flags are not included when the field is not optional.)
This makes sense to me because all version-N extension additions must be _represented_ in the encoding if you are a version-N implementation, and extension additions that are not optional must also be _present_--their value must be encoded. Optional extension additions are always represented by their corresponding bits in the bit field; if they are present, their value is also encoded.
The presense or absence of the OPTIONAL flag in an extension does not change the PER encoding of the SEQUENCE. In order to avoid previously mentioned problems, application may use a version of ASN.1 notation that has extra OPTIONAL keyword after each extension.
Some extension additions are defined as OPTIONAL and some not, presumably for a reason. Indicating that a non-optional one is not present would produce an encoding with a semantic error, while not an encoding syntax error, per se.
Solution 1: Clarification to the PER Encoding Process
The text in PER document (X.691, 1994) is somewhat ambiguous how many bits should be included in the extension present bitfield of SEQUENCE. To quote verbatim: "Let the number of extension additions in the type being encoded be "n", then a bit-field with "n" bits shall be produced for addition to the field-list." (Is the "type being encoded" the abstract syntax or an actual value like { bar 1, baz 2 }?)
If you'll notice, X.691 is very careful about its use of "type" and "value." Specifically, "abstract syntax value: A value of an abstract syntax (defined as the set of values of a single ASN.1 type), which is to be encoded by PER, or which is to be generated by PER encoding." I am sure that X.691 is referring to, in our case, the ASN.1 syntax defined in the version of the Recommendation identified by the protocolIdentifier.
However, the 0 bits at the end of extension present bitfield can be left out without changing the resulting semantics: the corresponding extensions are not present. As a result, the PER encoding does not change after a new extension is added to the ASN.1 specification.
Syntactically, one could leave out the last N extension additions (regardless of whether any are OPTIONAL, they are still represented in some way); however, this would result in a semantic error because "a bit-field with 'n' bits" was not "produced" where "n" is "the number of extension additions in the type being encoded." Just as with a field in the extension root, one may not simply choose to not encode an extension addition that is defined in the version of the Recommendation that you identify in your protocolIdentifier field.
This solution, while leaving H.225.0 v2 protocol as it is, requires however changes to some existing ASN.1 compilers, and in a pessimal case, to the X.691 standard text, too.
I see know reason to modify compilers or X.691. If one obeys the rules, everything works. Clarification text may be needed, however.
-- Paul Long Smith Micro Software, Inc.
"EXT Paul Long" plong@smithmicro.com writes:
B decodes the Foo, removes ICV and encodes the packet again. In the resulting encoding, the length of extension bitfield is 3, and the ICV that B regenerates is different that A generated and sent to B. B is not able to interwork with systems using earlier version of the ASN.1 spec.
Why not? This is precisely what the H.225.0 and H.245 protocolIdentifier is for--to indicate which version of the Recommendation the endpoint supports. An endpoint must know what protocol versions the remote terminal supports. For example, if an H.225.0v3 endpoint communicates with a v2 endpoint, it knows that the v2 endpoint will not recognize any of the extensions added since v2 and shall not therefore depend on any v3 behavior on the part of the v2 endpoint. Likewise, the v2 endpoint must be able to treat all v2 and subsequent endpoints as a v2 endpoint.
The whole point of ASN.1 extensions is that a version-N device can encode a PDU using version-N encoding rules and send it to a device using the version encoding rules of a previous version and the recipient can still decode the packet. However, due to the way ICV is calculated, a version-N device needs separate ASN.1 PER encoding/decoding functions for all previous version.
...
There are also problems because the way some ASN.1 compilers behave. Using our previous example, when A receives Foo with the importantExtension field from B, A has somehow to include the value when it is re-encoding Foo in order to calculate the ICV.
I can't think of a situation where a terminal would ever have to re-encode. Are you referring to a GK or GW?
All recipients must re-encode the PDU when checking ICV.
Pekka Pessi
Pekka,
I'm confused by a couple of your statements.
The presence of the extention markers is included in the PER encoding (by a single bit at the beginning) but the addition of extentions at a later time should not change any of the encodings of the 'base' structure. Any extentions that are added, end up following the PER structure and are actually encoded as BER 'chunks' so that earlier revisions of the protocol may skip over the ones not understood.
I'm confused as to your example of encoding - decoding - re-encoding The ICV _will_ have to be recalculated. The ICV is calculated after the ASN.1 structure is fully encoded (but excluding the ICV field itself) and just before it is sent out 'on the wire'. The ICV value may in fact change value, and even position, but it should always be recognized by rev2 and newer implementations. Rev1 obviously will ignore it and not generate one to send out....
jimt.
11:12 AM 6/24/98 +0300, Pekka Pessi wrote:
Hello, While debugging our ASN.1/PER encoder, I noticed a problem with the way ICV is calculated in H.225.0. Briefly, the PER encodings change when a SEQUENCE type is further extended, even if the new extension additions are not included in the SEQUENCE value. The issue prevents interoperability between software using H.225.0 version 2 and software using any version, it should be solved before any version 2 devices are released. Pekka Pessi
h2250-integrityCheckValue-problem.txt Pekka Pessi
$Revision: 1.1 $ Nokia Research
Center
June
1998
Comments on H.225.0 (1998): Problems When Calculating integrityCheckValue
The current H.225.0 algorithm for calculating the ICV does not work well with the PER extension mechanism. In order to interwork, each H.323 device needs a separate PER encoding function for each version of H.225.0 ASN.1 definitions.
Algorithm for Calculating integityCheckValue
According to the H.225.0 v2, integrityCheckValue is defined and calculated as follows:
ICV ::= SEQUENCE { algorithmOID OBJECT IDENTIFIER, -- the algorithm used to compute the
signature
icv BIT STRING -- the computed cryptographic integrity
check
-- value or signature
}
integrityCheckValue - provides improved message integrity/message authentication of the RAS messages. The cryptographically based integrity check value is computed by the sender applying a negotiated integrity algorithm and the secret key upon the entire message. Prior to integrityCheckValue computation this field shall be ignored and shall be empty. After computation, the sender puts the computed integrity check value in the integrityCheckValue field and transmits the message.
The above algorithm (AFAIK I have understood it correctly) assumes that the sender and receiver can encode the PDU exactly in the same way. It is a reasonable assumption, as PER produces only one possible (canonical) encoding for given PDU. However, there is a serious problem: the canonical representation changes if the ASN.1 SEQUENCE type is extended later.
PER Encoding of an Extended ASN.1 SEQUENCE
In the PER encoding of extensions to SEQUENCE types, the encoder first encodes the number of extensions as a normally small non-negative integer, then a bit field with one bit for each extension followed by the extensions itself (bit is one if the extension is present, zero if not). The encoding of each extension is preceded by the length of their encoding in octets.
Now, if the sender A uses following ASN.1 definition for a SEQUENCE
Foo ::= SEQUENCE { bar INTEGER (0..127), ..., baz INTEGER (0..255) OPTIONAL, integrityCheckValue ICV OPTIONAL }
When encoding this, the length of extension bitfield is 2. However, recipient B is using extended version of Foo like this:
Foo ::= SEQUENCE { bar INTEGER (0..127), ..., baz INTEGER (0..255) OPTIONAL, integrityCheckValue ICV OPTIONAL, importantExtension SomeType OPTIONAL }
B decodes the Foo, removes ICV and encodes the packet again. In the resulting encoding, the length of extension bitfield is 3, and the ICV that B regenerates is different that A generated and sent to B. B is not able to interwork with systems using earlier version of the ASN.1 spec.
ASN.1 Compilers Don't Grok Unknown Extensions
There are also problems because the way some ASN.1 compilers behave. Using our previous example, when A receives Foo with the importantExtension field from B, A has somehow to include the value when it is re-encoding Foo in order to calculate the ICV. However, it may be very hard to present an value of an unknown extension to the ASN.1 encoding functions. As a possible solution the ICV calculation could be included in the ASN.1 decoding process.
Problems with Non-OPTIONAL Extensions
Another problem with some ASN.1 compilers is inclusion of non-OPTIONAL extensions. Let us assume that software C uses following ASN.1 definition for Foo:
Foo ::= SEQUENCE { bar INTEGER (0..127), ..., baz INTEGER (0..255) OPTIONAL, integrityCheckValue ICV OPTIONAL, importantExtension SomeType OPTIONAL, criticalExtension OtherType }
There are two kinds of problems with an extension like criticalExtension. First, the encoder may try to ensure that all encoded PDUs conform to the specification and signal an error when a PDU without criticalExtension is encoded. Another problem is that the intermediate representation produced by the ASN.1 compiler may not provide means for application to express that criticalExtension is not present. (In other words, the produced structure usually contains a flag telling whether an optional field is present or not. Such flags are not included when the field is not optional.)
The presense or absence of the OPTIONAL flag in an extension does not change the PER encoding of the SEQUENCE. In order to avoid previously mentioned problems, application may use a version of ASN.1 notation that has extra OPTIONAL keyword after each extension.
Solution 1: Clarification to the PER Encoding Process
The text in PER document (X.691, 1994) is somewhat ambiguous how many bits should be included in the extension present bitfield of SEQUENCE. To quote verbatim: "Let the number of extension additions in the type being encoded be "n", then a bit-field with "n" bits shall be produced for addition to the field-list." (Is the "type being encoded" the abstract syntax or an actual value like { bar 1, baz 2 }?) However, the 0 bits at the end of extension present bitfield can be left out without changing the resulting semantics: the corresponding extensions are not present. As a result, the PER encoding does not change after a new extension is added to the ASN.1 specification.
This solution, while leaving H.225.0 v2 protocol as it is, requires however changes to some existing ASN.1 compilers, and in a pessimal case, to the X.691 standard text, too.
Solution 2: Hack
The receiving application does not decode and the re-encode the PDU, but rather removes the ICV from the encoded PDU. In practice, this requires
that
application can identify PER-encoded fields within the PDU and it can regenerate them, i.e. it has effectively the same functionality as a PER encoder/decoder.
Solution 3: Calculating ICV Differently
The following algorithm for generating and checking the ICV makes it possible to avoid all the previously mentioned problems. The problems are avoided by breaking the protocol layering, the application changes
directly
the PER-encoded PDU:
integrityCheckValue - provides improved message integrity/message authentication of the RAS messages. The cryptographically based integrity check value is computed by the sender applying a negotiated integrity algorithm and the secret key upon the entire message. Prior to integrityCheckValue computation an ICV with a previously agreed magic value (or key when using MDC) will be inserted to this field. The magic value will contain same algorithmOID and exactly as many bits in the icv BIT STRING as the computed value. After computation, the sender replaces the magic value with the computed integrity check value and transmits message. The receiver decodes message, replaces the received integrity value with the magic value, calculates the ICV and compares it with the received value.
NOTE: The sender or receiver can encode the ICV separately and replace it directly within the encoded PDU, when the magic ICV and computed ICV have exactly the same length. When replacing ICV value within an encoded PDU, re-encoding the whole PDU can be avoided.
NOTE: The above algorithm does not require directly changing the PER-encoded PDU. Like the current algorithm, ICV can be replaced with a new value above presentation layer then PDU will be re-encoded. It makes it easy, however: as the magic value is a very unique octet-aligned bit pattern (random data of 64 bits or more, probably), it should be easy to spot and replace it from the encoded PDU.
NOTE: It is not advisable to use magic value as the key to MAC algorithm.
Example code:
int icv_replace( u_char *msg, size_t len, u_char const *icv, u_char const *magic, size_t ilen) { u_char *m, *mim; size_t i, j, ilen_in_octets, ilen_in_full_octets; ilen_in_octets = (ilen + 7) >> 3; ilen_in_full_octets = ilen >> 3; /* find magic value from message */ for (m = msg, mim = NULL; m - msg < len - ilen_in_octets; m++) { /* NOTE: the magic value/icv may not be integral number of
octets */
for (i = 0; i < ilen_in_full_octets; i++) { if (m[i] != magic[i]) break; } if (i == ilen_in_full_octets) { if (mim) return -2; /* failure: two or more magic values found */ mim = m; } } if (mim == NULL) { return -1; /* failure: no magic value found */ /* replace magic value with icv */ for (i = 0; i < ilen_in_octets; i++) { mim[i] ^= magic[i] ^ icv[i]; } return 0; /* success */ }
Solution 4:
Fourth alternative is to treat encoded RasMessage as octet string. IVC can be calculated over that octet string and appended to the PDU on separate layer. E.g., RAS PDU could be defined as follows:
RasMessage ::= CHOICE {
--8<----8<----8<----8<----8<----8<----8<----8<----8<----8<-- -- all previous RasMessage CHOICEs are here --8<----8<----8<----8<----8<----8<----8<----8<----8<----8<-- authenticatedRasMessage SEQUENCE { plainRasMessage OCTET STRING, ivc IVC, ... } }
***************************************************** *** +1-503-264-8816(voice) Intel - Hillsboro, OR. *** *** mailto:jim.toga@intel.com mailto:james.toga@itu.ch *** *** PGP keyID 36 07 86 49 7D 74 DF 57 50 CB BA 32 08 9C 7C 41 *** *****************************************************
"EXT Jim Toga" jim.toga@intel.com writes:
I'm confused by a couple of your statements.
The presence of the extention markers is included in the PER encoding (by a single bit at the beginning) but the addition of extentions at a later time should not change any of the encodings of the 'base' structure. Any extentions that are added, end up following the PER structure and are actually encoded as BER 'chunks' so that earlier revisions of the protocol may skip over the ones not understood.
Well, this is slightly incorrect. A SEQUENCE type with extension additions is encoded as follows (see X.691 paragraphs 18.6 - 18.9):
* extension marker at the beginning of SEQUENCE is encoded as 1 bit
* the base structure is encoded
* number of extensions is encoded as "normally small length"
* a bit field with a bit for each extension is encoded (bit is one if the extension is present, zero if not)
* present extensions are encoded as open type fields, i.e., normal PER encoding of the extension addition preceded by its length as octets
Here is a concrete example (I hope). There are two ASN.1 SEQUENCEs like this, one from hypothetical version 2, second from version 3:
Byte ::= INTEGER (0 .. 255)
Type-v2 ::= SEQUENCE { foo Byte, ..., bar Byte OPTIONAL }
value-v2 Type-v2 ::= { foo 85, bar 170 }
Type-v3 ::= SEQUENCE { foo Byte, ..., bar Byte OPTIONAL, baz Byte OPTIONAL }
value-v3 Type-v3 ::= { foo 85, bar 170 }
We encode value-v2 and value-v3 with PER. Results look like this:
80 55 01 01 aa 80 55 03 00 01 aa
I'll go through the structure of value-v3:
hex binary 80 1xxxxxxx Extension bit (1 means that there are some extensions present) followed by 7 bits for alignment 55 01010101 foo 85 03 0000001 number of extension additions minus 1 = 1 1 first bit of bitfield, indicating "bar" is present 00 0xxxxxxx second bit of bitfield, indicating "baz" is not present, followed by 7 bits for alignment 01 00000001 lenght of "bar" in octets aa 10101010 bar 170
As you notice, the second addition, baz, changed the encoding even if it is not present in the SEQUENCE!
I'm confused as to your example of encoding - decoding - re-encoding The ICV _will_ have to be recalculated. The ICV is calculated after the ASN.1 structure is fully encoded (but excluding the ICV field itself) and just before it is sent out 'on the wire'. The ICV value may in fact change value, and even position, but it should always be recognized by rev2 and newer implementations. Rev1 obviously will ignore it and not generate one to send out....
Receiver must decode the PDU, re-encode the PDU without ICV, calculate the ICV over the re-encoded PDU and compare the result with the ICV from decoded PDU. If the ASN.1 version that receiver has (like Type-v3 above) differs from the version that sender has (like Type-v2 above), the re-encoded PDU differs from the PDU over which the sender calculated ICV. Naturally the ICV also differs.
I hope this cleared some confusion.
Pekka Pessi
Pekka,
Ok... I think we're both right (maybe you, more than me....)
The extentions do not change any of the encoding of the base structure. If the ICV is figured on these field values only, then it will not change no matter what the encode of extention entries. This obviously only protects the integrity of v1 fields in RAS messages. Suboptimal.
In terms of checking the ICV (given the above) the receiver can simply compute the ICV on the encoded PDU and check it against the value that was passed in the PDU. The ICV is generated on the wire encoded value and excludes/initializes the field it is stored in... so I still don't see the problem here.
As to the more pressing extention field problem.... I guess I was thinking all along that you #3 explanation (previous mail) was the way things would work in general. Maybe Martin Euchner (Siemens) the source of this particular functionality in H.235 would care to comment.
Regards,
jimt.
At 03:49 PM 6/25/98 +0300, Pekka Pessi wrote:
"EXT Jim Toga" jim.toga@intel.com writes:
I'm confused by a couple of your statements.
The presence of the extention markers is included in the PER encoding (by a single bit at the beginning) but the addition of extentions at a later time should not change any of the encodings of the 'base' structure. Any extentions that are added, end up following the PER structure and are actually encoded as BER 'chunks' so that earlier revisions of the protocol may skip over the ones not understood.
Well, this is slightly incorrect. A SEQUENCE type with extension additions is encoded as follows (see X.691 paragraphs 18.6 - 18.9): * extension marker at the beginning of SEQUENCE is encoded as 1 bit * the base structure is encoded * number of extensions is encoded as "normally small length" * a bit field with a bit for each extension is encoded (bit is one if the extension is present, zero if not) * present extensions are encoded as open type fields, i.e., normal PER encoding of the extension addition preceded by its length as octets Here is a concrete example (I hope). There are two ASN.1 SEQUENCEs like this, one from hypothetical version 2, second from version 3:
Byte ::= INTEGER (0 .. 255)
Type-v2 ::= SEQUENCE { foo Byte, ..., bar Byte OPTIONAL }
value-v2 Type-v2 ::= { foo 85, bar 170 }
Type-v3 ::= SEQUENCE { foo Byte, ..., bar Byte OPTIONAL, baz Byte OPTIONAL }
value-v3 Type-v3 ::= { foo 85, bar 170 }
We encode value-v2 and value-v3 with PER. Results look like this:
80 55 01 01 aa 80 55 03 00 01 aa
I'll go through the structure of value-v3:
hex binary 80 1xxxxxxx Extension bit (1 means that there are some extensions present) followed by 7 bits for alignment 55 01010101 foo 85 03 0000001 number of extension additions minus 1 = 1 1 first bit of bitfield, indicating "bar" is present 00 0xxxxxxx second bit of bitfield, indicating "baz" is not present, followed by 7 bits for alignment 01 00000001 lenght of "bar" in octets aa 10101010 bar 170
As you notice, the second addition, baz, changed the encoding even if it is not present in the SEQUENCE!
I'm confused as to your example of encoding - decoding - re-encoding The ICV _will_ have to be recalculated. The ICV is calculated after the ASN.1 structure is fully encoded (but excluding the ICV field itself) and just before it is sent out 'on the wire'. The ICV value may in fact change value, and even position, but it should always be recognized by rev2 and newer implementations. Rev1 obviously will ignore it and not generate one to send out....
Receiver must decode the PDU, re-encode the PDU without ICV, calculate the ICV over the re-encoded PDU and compare the result with the ICV from decoded PDU. If the ASN.1 version that receiver has (like Type-v3 above) differs from the version that sender has (like Type-v2 above), the re-encoded PDU differs from the PDU over which the sender calculated ICV. Naturally the ICV also differs. I hope this cleared some confusion. Pekka Pessi
***************************************************** *** +1-503-264-8816(voice) Intel - Hillsboro, OR. *** *** mailto:jim.toga@intel.com mailto:james.toga@itu.ch *** *** PGP keyID 36 07 86 49 7D 74 DF 57 50 CB BA 32 08 9C 7C 41 *** *****************************************************
participants (4)
-
Jim Toga
-
Paul Long
-
Pekka Pessi
-
Pekka Pessi