| 749 | |
| 750 | |
| 751 | class _ExtensionsLenField(FieldLenField): |
| 752 | def getfield(self, pkt, s): |
| 753 | """ |
| 754 | We try to compute a length, usually from a msglen parsed earlier. |
| 755 | If we can not find any length, we consider 'extensions_present' |
| 756 | (from RFC 5246) to be False. |
| 757 | """ |
| 758 | ext = pkt.get_field(self.length_of) |
| 759 | tmp_len = ext.length_from(pkt) |
| 760 | if tmp_len is None or tmp_len < 0: |
| 761 | v = pkt.tls_session.tls_version |
| 762 | if v is None or v < 0x0304: |
| 763 | return s, None |
| 764 | return super(_ExtensionsLenField, self).getfield(pkt, s) |
| 765 | |
| 766 | def addfield(self, pkt, s, i): |
| 767 | """ |
| 768 | There is a hack with the _ExtensionsField.i2len. It works only because |
| 769 | we expect _ExtensionsField.i2m to return a string of the same size (if |
| 770 | not of the same value) upon successive calls (e.g. through i2len here, |
| 771 | then i2m when directly building the _ExtensionsField). |
| 772 | |
| 773 | XXX A proper way to do this would be to keep the extensions built from |
| 774 | the i2len call here, instead of rebuilding them later on. |
| 775 | """ |
| 776 | if i is None: |
| 777 | if self.length_of is not None: |
| 778 | fld, fval = pkt.getfield_and_val(self.length_of) |
| 779 | |
| 780 | tmp = pkt.tls_session.frozen |
| 781 | pkt.tls_session.frozen = True |
| 782 | f = fld.i2len(pkt, fval) |
| 783 | pkt.tls_session.frozen = tmp |
| 784 | |
| 785 | i = self.adjust(pkt, f) |
| 786 | if i == 0: # for correct build if no ext and not explicitly 0 |
| 787 | v = pkt.tls_session.tls_version |
| 788 | # With TLS 1.3, zero lengths are always explicit. |
| 789 | if v is None or v < 0x0304: |
| 790 | return s |
| 791 | else: |
| 792 | return s + struct.pack(self.fmt, i) |
| 793 | return s + struct.pack(self.fmt, i) |
| 794 | |
| 795 | |
| 796 | class _ExtensionsField(StrLenField): |
no outgoing calls
no test coverage detected
searching dependent graphs…