Subject: Re: [IPsec] IPsec Digest, Vol 68, Issue 49

From: Keith Welter <[email-masked]>
Date: Mon, 4 Jan 2010 18:08:31 -0800

Tero Kivinen writes:
> David Wierbowski writes:
> > I think it is reasonable to expect that an IKEv2 bis implementation 
would
> > use an IF statement to control sending the new Notify types.
> 
> No they should just use new notifies, as all old complient
> implementations will work with those new error messages also.
They will work when an unrecognized notify type is received but they 
may not work as well as if they had received a recognized notify 
type such as NO_PROPOSAL_CHOSEN. 

> 
> There is no reason to send old error notifications.
A recognized (old) notify type like NO_PROPOSAL_CHOSEN may be used as a 
hint 
to do something special like try again later, a notion the RFC 4718 
authors 
exploited because they didn't have the luxury of introducing new notify 
types. 
So, sending a new notify type to a peer that does not recognize it could
be viewed as preventing the peer from making the most informed decision.

> 
> > If the minor number was changed an implementation could check the
> > minor version and send the new notify types when the minor version
> > was 1 and send the notify types recommended in RFC 4718 if the minor
> > number was 0.
> 
> There is no point of supporting old RFC4718 error notifications after
> you implement IKEv2bis as new error notifications are backward
> compatible with old ones. 
I think there is a point to supporting the old notifies.  If you have a 
deployed implementation then you have to consider patching it to at least 
recognize the new notification types.  If you have an undeployed 
implementation in development you still might have to interoperate with 
unpatched peers.  On the other hand, if ikev2bis increments the minor 
version number then you may code the ikev2bis implementation to not send 
the new notify types to down-level peers rather than patching already 
deployed implementations.

I also think that calling the new error notifications "backwards 
compatible"
is misleading.  If you send a new notification to a peer that does not 
recognize it then the behavior may be different, possibly worse, than if 
you had sent an old, recognized notification.

> Also RFC4718 used text like "thus failing
> the request with something non-fatal such as NO_PROPOSAL_CHOSEN seems
> like a reasonable approach." which clearly indicates that other error
> notifications are also possible, thus whether other end sends
> NO_PROPOSAL_CHOSEN or CHILD_SA_NOT_FOUND error notification, as
> recipient will process them both in a same way, and expect that
> exchange failed. 
The quoted RFC 4718 text suggested using a "non-fatal" notify type.
However, a new notify type if it is unrecognized by the peer constitutes
a fatal notify type.  The recipient will probably not process 
NO_PROPOSAL_CHOSEN and an unrecognized error-type notify the same way.

> 
> > That is what my implementation plans to do if the minor version
> > number is bumped.
> 
> I do not think I will ever implement RFC4718 error notifications (we
> have not implemented it yet, and now when we have IKEv2bis almost
> ready, I do not think we ever will), thus for me it does not really
> matter, but I think it would be much easier to just change those error
> notifications you already have in the code to use CHILD_SA_NOT_FOUND
> and TEMPORARY_FAILURE instead of NO_ADDITIONAL_SAS and
> NO_PROPOSAL_CHOSEN without adding any extra logic based on the minor
> version number.
> 
> > I'm not sure I agree with Tero that an implementation getting an 
unknown
> > TEMPORARY_FAILURE notify would always take the same action that it 
would if
> > it received NO_PROPOSAL_CHOSEN as suggested by RFC 4718.
> 
> Then it is not complient to RFC4306, as RFC4306 clearly says that if
> you get uknown error notification then you "MUST assume that the
> corresponding request has failed entirely".
Certainly an RFC 4306 compliant implementation would fail a "request"
entirely if it got an unknown error notification in the response. 
However, an RFC 4306 compliant implementation might also retry the request 

later with a different message ID after receiving NO_PROPOSAL_CHOSEN 
whereas 
it almost certainly would not do such a thing after receiving an unknown 
error notification. 

> 
> RFC4718 does not (and cannot) modify the meaning of NO_PROPOSAL_CHOSEN
> error notification it just gives you examples what kind error
> notifications could be used in which case, but I do not think it gives
> you instructions what to do when you receive such error notifications.
> 
> This was one of the things needed to be added to the IKEv2bis, and
> that was the reason we needed to have separate error notifications as
> we wanted to be sure that it is easy to decide what to do when you get
> error notification back (i.e. in addition to assuming that exchange
> failed). 
> -- 
> [email-masked]

I think this thread has been heading in the direction that 
it is not necessary to increment the minor version based on the
incorrect assertion that old implementations will work just as 
well when they receive the new notify types as they did before. 
Old implementations will continue to work but they may not work 
*as well* when the new notify types are introduced unless the old 
implementations are patched.  Some old implementations may even 
work worse if they receive the new notifications rather than those 
originally suggested in RFC 4718 section 5.11.10.

I think there is a tangible benefit to be gained from incrementing
the minor version number.  Specifically, to enable an implementation
to avoid sending the new notify types to a peer that won't recognize 
them.  I understand the potential risk of incrementing the minor version 
but I think we ought to weigh that against the potential benefits.

Keith Welter

---

From: Tero Kivinen <[email-masked]>
Date: Tue, 5 Jan 2010 14:24:16 +0200

Keith Welter writes:
> A recognized (old) notify type like NO_PROPOSAL_CHOSEN may be used
> as a hint to do something special like try again later, a notion the
> RFC 4718 authors exploited because they didn't have the luxury of
> introducing new notify types. So, sending a new notify type to a
> peer that does not recognize it could be viewed as preventing the
> peer from making the most informed decision.

The RFC4718 didn't give any specific instructions what to do when
implementation receives those notify types.

Also when telling which error to send it uses terms like:

   "... thus failing the request with something non-fatal such as
    NO_PROPOSAL_CHOSEN seems like a reasonable approach."

    "In both cases, NO_PROPOSAL_CHOSEN is probably fine."

    "... replying with NO_PROPOSAL_CHOSEN is probably reasonable:"

    "Our proposal is as follows: if a host receives a request to rekey
     the IKE_SA when it has CHILD_SAs in "half-open" state (currently
     being created or rekeyed), it should reply with
     NO_PROPOSAL_CHOSEN. If a host receives a request to create or
     rekey a CHILD_SA after it has started rekeying the IKE_SA, it
     should reply with NO_ADDITIONAL_SAS."

    "Our recommendation is that if a host receives a request to rekey
     the IKE_SA when it has CHILD_SAs in "half-closed" state
     (currently being closed), it should reply with
     NO_PROPOSAL_CHOSEN."

    "At this point, host B should probably reply with
     NO_PROPOSAL_CHOSEN, and host A should reply as usual, close the
     IKE_SA, and stop retransmitting req1."

All these uses terms where NO_PROPOSAL_CHOSEN is given out more like
and example than specific error.

The summary section does not use "probably / such as / our proposal /
our recommendation" anymore, it summarizes what has been said in other
sections before.

As the RFC4718 didn't give any instructions what to do when you
receive any of those error notifications, I assumed it expected the
normal non-fatal (to IKE SA) error notification processing, i.e. it
really does not matter what non-fatal error notification you use, as
it should cause the exchange to fail which is the only meaning for
sending that error notification.

That was the reason I wanted to have new notification, so we can
actually define some other processing to happen when those are
received. I.e. we can say "When a peer receives a TEMPORARY_FAILURE
notification, it MUST NOT immediately retry the operation...".

That kind of behavior cannot be specified for NO_PROPOSAL_CHOSEN and
that kind of behavior is NOT specified for it. On the other hand as
only behavior which is defined for NO_PROPOSAL_CHOSEN is the generic
non-fatal error notification behavior, meaning the exchange failed,
but nothing else, that means any new error notification will get same
behavior from complient implementations.

If implementation do add some extra handling for the
NO_PROPOSAL_CHOSEN error notifications, that is their own decision and
it is not required or specified in the standard. 

> recognize the new notification types.

This is something you can do, i.e. if you already support old
NO_PROPOSAL_CHOSEN notifications and recognize them based on the
current state to be caused by exchange collisions you can (and should)
still do that.

On the other hand new implementations does not need to do that. For
them it should be enough to do special processing for
TEMPORARY_FAILURE only, for all other non-fatal error notifications
they can do default processing (which will still take care of the
RFC4718 way of doing things, as the default processing is to make that
exchange fail). 

> If you have an undeployed implementation in development you still
> might have to interoperate with unpatched peers.

Regadless what error notification you use, you WILL interoperate with
unpatched peers (unless they did something against RFC4306). Note,
that there are implementations out there which do not implement
RFC4718 exchange collisions at all, which means you still need to make
sure you handle those cases too if you really want optimal processing
with all implementations out there..

> On the other hand, if ikev2bis increments the minor version number
> then you may code the ikev2bis implementation to not send the new
> notify types to down-level peers rather than patching already

There is no need for that, as someone might have already disagreed
with RFC4718 and selected some other error notifications, as RFC4718
uses text like "...something non-fatal such as..." or "is probably
fine", so you shouldn't really be looking at the specific error
(NO_PROPOSAL_CHOSEN) but the fact that you got any non-fatal (to IKE
SA) error back when you were at state where there might be collisions.

> compatible" is misleading. If you send a new notification to a peer
> that does not recognize it then the behavior may be different,
> possibly worse, than if you had sent an old, recognized
> notification.

Not really, as RFC4306 or RFC4718 didn't give you any instructions
what to do when you receive such error notifications, and those error
notifications given in RFC4718 were mostly given out as examples, thus
your code should work similarly regardless what error notification you
get.

As none of the RFC gaven any specific instructions what to do when you
receive those error messages that means the new error notifications
are backward compatible. Some implementations might have special
behavior not specified in the RFCs which might need to be changed, but
document modifications we are proposing would still be backward
compatible.

The reason RFC4718 selected NO_PROPOSAL_CHOSEN was not to add some
special processing for it, but because it happened to be non-fatal
error code which didn't really have any special meaning for it.

Most of the other non-fatal error codes had some special handling
attached to it (UNSUPPORTED_CRITICAL_PAYLOAD, INVALID_IKE_SPI,
INVALID_MAJOR_VERSION, INVALID_MESSAGE_ID, INVALID_SPI,
INVALID_KE_PAYLOAD, SINGLE_PAIR_REQUIRED, NO_ADDITIONAL_SAS,
INTERNAL_ADDRESS_FAILURE, FAILED_CP_REQUIRED, INVALID_SELECTORS).

The other option could have been TS_UNACCEPTABLE, but
NO_PROPOSAL_CHOSEN was selected. There was no way of adding new
meaning to the error notification, which is why RFC4718 didn't specify
any special handling when you receive the error notification, it just
assumed the default processing is ok.

> However, a new notify type if it is unrecognized by the peer
> constitutes a fatal notify type. The recipient will probably not
> process NO_PROPOSAL_CHOSEN and an unrecognized error-type notify the
> same way.

New error notifications are non-fatal just as NO_PROPOSAL_CHOSEN. Only
fatal notification types are those which cause IKEv2 SA to be teared
down, i.e. AUTHENTICATION_FAILED and INVALID_SYNTAX error
notifications are considered fatal.

All other error notifications are non-fatal, and only cause the
current exchange to be considered as failed. RFC4306 (or RFC4718)
didn't specify which error notifications are fatal and which are not,
but we already added that text to the IKEv2bis.

> Certainly an RFC 4306 compliant implementation would fail a
> "request" entirely if it got an unknown error notification in the
> response. However, an RFC 4306 compliant implementation might also
> retry the request later with a different message ID after receiving
> NO_PROPOSAL_CHOSEN whereas it almost certainly would not do such a
> thing after receiving an unknown error notification.

For TEMPORARY_FAILURE it should try again, for NO_PROPOSAL_CHOSEN that
might not be case.

If you really think that you get NO_PROPOSAL_CHOSEN only when you have
mismatching policy, that means that you should only try again when
your configuration has changed, or when the other ends configuration
has changed. As configuration changes are not something that happens
very often, it would be completely fine to retry after much longer
timeout after NO_PROPOSAL_CHOSEN (for example 5 minutes).

As most of the implementations do not really care about that, I think
most will simply fail the exchange and they will retry when the next
packet arrives that will trigger new Child SA to be created for the
same policy rule.

There is nothing in the documents which says you should not try again
(or text which says how often you should retry).

> well when they receive the new notify types as they did before. 

Yes. Old implementations should work regardless which error notify
they get.

> originally suggested in RFC 4718 section 5.11.10.

That might be case. And old implementations might have bugs processing
unknown error notifications, but on the other hand old implementations
might also have bugs in the processing of new minor version number.

> but I think we ought to weigh that against the potential benefits.

All of these exchange collision cases are quite rare. There are really
only two of those which are bit more common and one of them is
important, i.e. simultaneous IKE SA rekey, and simultaneous Child SA
rekey. For both of them there is already text which says how to handle
them.

Also for simultaneous Child SA rekey even if it is not handled
properly only thing that happens is that we have one extra Child SA,
but traffic continues to flow and everything works.

Only one where it is important to handle it properly is the
simultaneous IKE SA rekey, as it is important to know that both ends
agree on where the child SAs are moved.

As I said these exchange collisions are not something you see very
often (if ever) and I do not think the optimal behavior in all of
those cases between RFC4718 and IKEv2 bis versions is needed that much
that people would need to care about that. RFC4718 and IKEv2bis
versions will interoperate and work together, there might be some
extra packets going on in case the RFC4718 version do not understand
new error notifications coming from the IKEv2bis version and does not
delay retrying at all but would delay retrying if it would receive
NO_PROPOSAL_CHOSEN.

There might also be broken versions which do not retry at all if they
receive any other error notification than NO_PROPOSAL_CHOSEN, but I
would consider those versions broken.
-- 
[email-masked]