ParseAuthenticatorBody decodes the body of an NTS Authenticator EF. Trailing bytes past the declared nonce + ciphertext are silently accepted: RFC 8915 §5.6 explicitly allows "Additional Padding (if any)" after the ciphertext, and we have no way to distinguish legitimate padding from stray bytes wi
(body []byte)
| 120 | // stray bytes without protocol-specific knowledge that doesn't belong at |
| 121 | // this layer. |
| 122 | func ParseAuthenticatorBody(body []byte) (AuthenticatorBody, error) { |
| 123 | var ab AuthenticatorBody |
| 124 | if len(body) < authenticatorHeaderLen { |
| 125 | return ab, fmt.Errorf("%w: header needs %d bytes, have %d", |
| 126 | ErrAuthenticatorTruncated, authenticatorHeaderLen, len(body)) |
| 127 | } |
| 128 | nonceLen := int(binary.BigEndian.Uint16(body[0:2])) |
| 129 | cipherLen := int(binary.BigEndian.Uint16(body[2:4])) |
| 130 | paddedNonceLen := padTo4(nonceLen) |
| 131 | paddedCipherLen := padTo4(cipherLen) |
| 132 | required := authenticatorHeaderLen + paddedNonceLen + paddedCipherLen |
| 133 | if required > len(body) { |
| 134 | return ab, fmt.Errorf("%w: required=%d body_len=%d nonce_len=%d cipher_len=%d", |
| 135 | ErrAuthenticatorTruncated, required, len(body), nonceLen, cipherLen) |
| 136 | } |
| 137 | ab.Nonce = make([]byte, nonceLen) |
| 138 | copy(ab.Nonce, body[authenticatorHeaderLen:authenticatorHeaderLen+nonceLen]) |
| 139 | ab.Ciphertext = make([]byte, cipherLen) |
| 140 | copy(ab.Ciphertext, body[authenticatorHeaderLen+paddedNonceLen:authenticatorHeaderLen+paddedNonceLen+cipherLen]) |
| 141 | return ab, nil |
| 142 | } |
| 143 | |
| 144 | // SealAuthenticator encrypts plaintext under the given AEAD, authenticating ad |
| 145 | // as associated data, and returns the result as an NTS Authenticator extension |
searching dependent graphs…