mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-17 12:09:27 +00:00
Harvest 176 isolated vuln-vs-fix functions (109 CVEs, 352 training rows) into benchmarks/pairs/vfc with provenance and a JSONL training manifest. Score the slice as an honesty dashboard (ousast pairs --slice vfc); keep the pair gate on the local fixtures only.
110 lines
3.4 KiB
C
110 lines
3.4 KiB
C
/* Provenance: OpenSSL tls1_process_heartbeat after Heartbleed bounds check.
|
|
* repo: openssl/openssl
|
|
* commit: 96db9023b881d7cd9f379b0c154650d6c108e9a3
|
|
* parent: 0d7717fc9c83dafab8153cbd5e2180e6e04cc802
|
|
* commit_url: https://github.com/openssl/openssl/commit/96db9023b881d7cd9f379b0c154650d6c108e9a3
|
|
* cve: CVE-2014-0160
|
|
* license: OpenSSL License
|
|
* function: tls1_process_heartbeat
|
|
* relpath: ssl/t1_lib.c
|
|
*/
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
typedef struct ssl_st {
|
|
struct {
|
|
struct {
|
|
unsigned char *data;
|
|
unsigned int length;
|
|
} rrec;
|
|
} *s3;
|
|
int version;
|
|
void (*msg_callback)(int write_p, int version, int content_type, const void *buf, size_t len, void *ssl, void *arg);
|
|
void *msg_callback_arg;
|
|
unsigned int tlsext_hb_seq;
|
|
unsigned int tlsext_hb_pending;
|
|
} SSL;
|
|
|
|
#define TLS1_RT_HEARTBEAT 24
|
|
#define TLS1_HB_REQUEST 1
|
|
#define TLS1_HB_RESPONSE 2
|
|
#define n2s(c, s) ((s = (((unsigned int)((c)[0])) << 8) | (((unsigned int)((c)[1])))), (c) += 2)
|
|
#define s2n(s, c) (((c)[0] = (unsigned char)(((s) >> 8) & 0xff), (c)[1] = (unsigned char)(((s)) & 0xff)), (c) += 2)
|
|
|
|
static unsigned char *OPENSSL_malloc(unsigned int n) { return (unsigned char *)malloc(n); }
|
|
static void OPENSSL_free(void *p) { free(p); }
|
|
static int RAND_pseudo_bytes(unsigned char *buf, unsigned int n) {
|
|
(void)buf;
|
|
(void)n;
|
|
return 1;
|
|
}
|
|
static int ssl3_write_bytes(SSL *s, int type, unsigned char *buf, unsigned int len) {
|
|
(void)s;
|
|
(void)type;
|
|
(void)buf;
|
|
return (int)len;
|
|
}
|
|
|
|
int tls1_process_heartbeat(SSL *s) {
|
|
unsigned char *p = &s->s3->rrec.data[0], *pl;
|
|
unsigned short hbtype;
|
|
unsigned int payload;
|
|
unsigned int padding = 16; /* Use minimum padding */
|
|
|
|
if (s->msg_callback)
|
|
s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, &s->s3->rrec.data[0], s->s3->rrec.length, s, s->msg_callback_arg);
|
|
|
|
/* Read type and payload length first */
|
|
if (1 + 2 + 16 > s->s3->rrec.length)
|
|
return 0; /* silently discard */
|
|
hbtype = *p++;
|
|
n2s(p, payload);
|
|
if (1 + 2 + payload + 16 > s->s3->rrec.length)
|
|
return 0; /* silently discard per RFC 6520 sec. 4 */
|
|
pl = p;
|
|
|
|
if (hbtype == TLS1_HB_REQUEST) {
|
|
unsigned char *buffer, *bp;
|
|
int r;
|
|
|
|
/* Allocate memory for the response, size is 1 bytes
|
|
* message type, plus 2 bytes payload length, plus
|
|
* payload, plus padding
|
|
*/
|
|
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
|
|
bp = buffer;
|
|
|
|
/* Enter response type, length and copy payload */
|
|
*bp++ = TLS1_HB_RESPONSE;
|
|
s2n(payload, bp);
|
|
memcpy(bp, pl, payload);
|
|
bp += payload;
|
|
/* Random padding */
|
|
RAND_pseudo_bytes(bp, padding);
|
|
|
|
r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
|
|
|
|
if (r >= 0 && s->msg_callback)
|
|
s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding, s, s->msg_callback_arg);
|
|
|
|
OPENSSL_free(buffer);
|
|
|
|
if (r < 0)
|
|
return r;
|
|
} else if (hbtype == TLS1_HB_RESPONSE) {
|
|
unsigned int seq;
|
|
|
|
/* We only send sequence numbers (2 bytes unsigned int),
|
|
* and 16 random bytes, so we just try to read the
|
|
* sequence number */
|
|
n2s(pl, seq);
|
|
|
|
if (payload == 18 && seq == s->tlsext_hb_seq) {
|
|
s->tlsext_hb_seq++;
|
|
s->tlsext_hb_pending = 0;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|