diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2014-07-12 13:11:54 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2014-07-12 13:11:54 +0000 |
commit | 68604b897713ece762fa7e3516b76ce6b919eda0 (patch) | |
tree | 5e3aba6dec9a536d85ae1cad4e94f4c167e7492b /lib | |
parent | 88314c75cf872ad59638cf1ec83d8e21bf72def5 (diff) |
Remove remnants from PSK, KRB5 and SRP.
ok beck@ miod@
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libssl/d1_clnt.c | 8 | ||||
-rw-r--r-- | lib/libssl/d1_srvr.c | 31 | ||||
-rw-r--r-- | lib/libssl/s3_clnt.c | 25 | ||||
-rw-r--r-- | lib/libssl/s3_pkt.c | 6 | ||||
-rw-r--r-- | lib/libssl/s3_srvr.c | 56 | ||||
-rw-r--r-- | lib/libssl/ssl_ciph.c | 62 | ||||
-rw-r--r-- | lib/libssl/ssl_lib.c | 5 | ||||
-rw-r--r-- | lib/libssl/ssl_locl.h | 9 |
8 files changed, 43 insertions, 159 deletions
diff --git a/lib/libssl/d1_clnt.c b/lib/libssl/d1_clnt.c index b85908c7330..004fd6e04f5 100644 --- a/lib/libssl/d1_clnt.c +++ b/lib/libssl/d1_clnt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: d1_clnt.c,v 1.29 2014/07/11 22:57:25 miod Exp $ */ +/* $OpenBSD: d1_clnt.c,v 1.30 2014/07/12 13:11:53 jsing Exp $ */ /* * DTLS implementation written by Nagendra Modadugu * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. @@ -395,9 +395,9 @@ dtls1_connect(SSL *s) s->init_num = 0; break; } - /* Check if it is anon DH or PSK */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && - !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + /* Check if it is anon DH. */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & + SSL_aNULL)) { ret = ssl3_get_server_certificate(s); if (ret <= 0) goto end; diff --git a/lib/libssl/d1_srvr.c b/lib/libssl/d1_srvr.c index 8531f2db2b9..a94b7ed61b1 100644 --- a/lib/libssl/d1_srvr.c +++ b/lib/libssl/d1_srvr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: d1_srvr.c,v 1.31 2014/07/12 10:06:04 jsing Exp $ */ +/* $OpenBSD: d1_srvr.c,v 1.32 2014/07/12 13:11:53 jsing Exp $ */ /* * DTLS implementation written by Nagendra Modadugu * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. @@ -427,9 +427,9 @@ dtls1_accept(SSL *s) case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: - /* Check if it is anon DH or normal PSK */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && - !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + /* Check if it is anon DH. */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & + SSL_aNULL)) { dtls1_start_timer(s); ret = dtls1_send_server_certificate(s); if (ret <= 0) @@ -500,22 +500,13 @@ dtls1_accept(SSL *s) * and in RFC 2246) ... except when the application * insists on verification (against the specs, but * s3_clnt.c accepts this for SSL 3). - * - * - We are using a Kerberos ciphersuite. - * - * - We are using normal PSK certificates and - * Certificate Requests are omitted */ if (!(s->verify_mode & SSL_VERIFY_PEER) || ((s->session->peer != NULL) && (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && !(s->verify_mode & - SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || - (s->s3->tmp.new_cipher->algorithm_auth & - SSL_aKRB5) || - (s->s3->tmp.new_cipher->algorithm_mkey & - SSL_kPSK)) { + SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) { /* no cert request */ skip = 1; s->s3->tmp.cert_request = 0; @@ -1216,8 +1207,7 @@ dtls1_send_server_key_exchange(SSL *s) n += 2 + nr[i]; } - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)) { if ((pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher, NULL)) == NULL) { al = SSL_AD_DECODE_ERROR; @@ -1463,12 +1453,9 @@ dtls1_send_server_certificate(SSL *s) if (s->state == SSL3_ST_SW_CERT_A) { x = ssl_get_server_send_cert(s); if (x == NULL) { - /* VRS: allow null cert if auth == KRB5 */ - if ((s->s3->tmp.new_cipher->algorithm_mkey != SSL_kKRB5) || - (s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5)) { - SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); - return (0); - } + SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE, + ERR_R_INTERNAL_ERROR); + return (0); } l = dtls1_output_cert_chain(s, x); diff --git a/lib/libssl/s3_clnt.c b/lib/libssl/s3_clnt.c index 884b9f1efb8..7d6681b3aca 100644 --- a/lib/libssl/s3_clnt.c +++ b/lib/libssl/s3_clnt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: s3_clnt.c,v 1.78 2014/07/11 22:57:25 miod Exp $ */ +/* $OpenBSD: s3_clnt.c,v 1.79 2014/07/12 13:11:53 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -339,11 +339,9 @@ ssl3_connect(SSL *s) s->init_num = 0; break; } - /* Check if it is anon DH/ECDH or PSK */ + /* Check if it is anon DH/ECDH. */ if (!(s->s3->tmp.new_cipher->algorithm_auth & - SSL_aNULL) && - !(s->s3->tmp.new_cipher->algorithm_mkey & - SSL_kPSK)) { + SSL_aNULL)) { ret = ssl3_get_server_certificate(s); if (ret <= 0) goto end; @@ -996,7 +994,6 @@ ssl3_get_server_certificate(SSL *s) SESS_CERT *sc; EVP_PKEY *pkey = NULL; - /* VRS: 0=> will allow null cert if auth == KRB5 */ int need_cert = 1; n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_A, @@ -1005,9 +1002,7 @@ ssl3_get_server_certificate(SSL *s) if (!ok) return ((int)n); - if ((s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) || - ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) && - (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE))) { + if ((s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE)) { s->s3->tmp.reuse_message = 1; return (1); } @@ -1098,12 +1093,6 @@ ssl3_get_server_certificate(SSL *s) pkey = X509_get_pubkey(x); - /* VRS: allow null cert if auth == KRB5 */ - need_cert = ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) && - (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) - ? 0 : 1; - - if (need_cert && ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey))) { x = NULL; @@ -1553,8 +1542,8 @@ ssl3_get_key_exchange(SSL *s) } } } else { - /* aNULL or kPSK do not need public keys */ - if (!(alg_a & SSL_aNULL) && !(alg_k & SSL_kPSK)) { + /* aNULL does not need public keys. */ + if (!(alg_a & SSL_aNULL)) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; @@ -2615,7 +2604,7 @@ ssl3_check_cert_and_algorithm(SSL *s) alg_a = s->s3->tmp.new_cipher->algorithm_auth; /* We don't have a certificate. */ - if ((alg_a & (SSL_aDH|SSL_aNULL|SSL_aKRB5)) || (alg_k & SSL_kPSK)) + if (alg_a & (SSL_aDH|SSL_aNULL)) return (1); sc = s->session->sess_cert; diff --git a/lib/libssl/s3_pkt.c b/lib/libssl/s3_pkt.c index 237d90c5812..cbd35ff7e3e 100644 --- a/lib/libssl/s3_pkt.c +++ b/lib/libssl/s3_pkt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: s3_pkt.c,v 1.49 2014/07/10 08:51:14 tedu Exp $ */ +/* $OpenBSD: s3_pkt.c,v 1.50 2014/07/12 13:11:53 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1134,10 +1134,6 @@ start: SSL_R_NO_RENEGOTIATION); goto f_err; } -#ifdef SSL_AD_MISSING_SRP_USERNAME - else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME) - return (0); -#endif } else if (alert_level == 2) { /* fatal */ s->rwstate = SSL_NOTHING; diff --git a/lib/libssl/s3_srvr.c b/lib/libssl/s3_srvr.c index 2d1bee1723d..e0a7d78995e 100644 --- a/lib/libssl/s3_srvr.c +++ b/lib/libssl/s3_srvr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: s3_srvr.c,v 1.76 2014/07/12 10:06:04 jsing Exp $ */ +/* $OpenBSD: s3_srvr.c,v 1.77 2014/07/12 13:11:53 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -373,13 +373,9 @@ ssl3_accept(SSL *s) case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: - /* Check if it is anon DH or anon ECDH, */ - /* normal PSK or KRB5 or SRP */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) - && !(s->s3->tmp.new_cipher->algorithm_mkey & - SSL_kPSK) - && !(s->s3->tmp.new_cipher->algorithm_auth & - SSL_aKRB5)) { + /* Check if it is anon DH or anon ECDH. */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & + SSL_aNULL)) { ret = ssl3_send_server_certificate(s); if (ret <= 0) goto end; @@ -417,10 +413,7 @@ ssl3_accept(SSL *s) /* * Only send if a DH key exchange, fortezza or - * RSA but we have a sign only certificate - * - * PSK: send ServerKeyExchange if PSK identity - * hint is provided + * RSA but we have a sign only certificate. * * For ECC ciphersuites, we send a serverKeyExchange * message only if the cipher suite is either @@ -428,13 +421,12 @@ ssl3_accept(SSL *s) * server certificate contains the server's * public key for key exchange. */ - if (s->s3->tmp.use_rsa_tmp - || (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH)) - || (alg_k & SSL_kEECDH) - || ((alg_k & SSL_kRSA) - && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == - NULL - ))) { + if (s->s3->tmp.use_rsa_tmp || + (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH)) || + (alg_k & SSL_kEECDH) || + ((alg_k & SSL_kRSA) && + (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == + NULL))) { ret = ssl3_send_server_key_exchange(s); if (ret <= 0) goto end; @@ -463,22 +455,13 @@ ssl3_accept(SSL *s) * and in RFC 2246) ... except when the application * insists on verification (against the specs, but * s3_clnt.c accepts this for SSL 3). - * - * - We are using a Kerberos ciphersuite. - * - * - We are using normal PSK certificates and - * Certificate Requests are omitted */ if (!(s->verify_mode & SSL_VERIFY_PEER) || ((s->session->peer != NULL) && (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && !(s->verify_mode & - SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || - (s->s3->tmp.new_cipher->algorithm_auth & - SSL_aKRB5) || - (s->s3->tmp.new_cipher->algorithm_mkey & - SSL_kPSK)) { + SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) { /* No cert request */ skip = 1; s->s3->tmp.cert_request = 0; @@ -1605,8 +1588,7 @@ ssl3_send_server_key_exchange(SSL *s) n += 2 + nr[i]; } - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && - !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)) { if ((pkey = ssl_get_sign_pkey( s, s->s3->tmp.new_cipher, &md)) == NULL) { al = SSL_AD_DECODE_ERROR; @@ -2681,15 +2663,9 @@ ssl3_send_server_certificate(SSL *s) if (s->state == SSL3_ST_SW_CERT_A) { x = ssl_get_server_send_cert(s); if (x == NULL) { - /* VRS: allow null cert if auth == KRB5 */ - if ((s->s3->tmp.new_cipher->algorithm_auth != - SSL_aKRB5) || - (s->s3->tmp.new_cipher->algorithm_mkey & - SSL_kKRB5)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, - ERR_R_INTERNAL_ERROR); - return (0); - } + SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, + ERR_R_INTERNAL_ERROR); + return (0); } l = ssl3_output_cert_chain(s, x); diff --git a/lib/libssl/ssl_ciph.c b/lib/libssl/ssl_ciph.c index 9df4f8a0c98..a2dec527ca1 100644 --- a/lib/libssl/ssl_ciph.c +++ b/lib/libssl/ssl_ciph.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_ciph.c,v 1.64 2014/07/12 07:52:36 guenther Exp $ */ +/* $OpenBSD: ssl_ciph.c,v 1.65 2014/07/12 13:11:53 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -273,11 +273,6 @@ static const SSL_CIPHER cipher_aliases[] = { }, { - .name = SSL_TXT_kKRB5, - .algorithm_mkey = SSL_kKRB5, - }, - - { .name = SSL_TXT_kECDHr, .algorithm_mkey = SSL_kECDHr, }, @@ -299,14 +294,6 @@ static const SSL_CIPHER cipher_aliases[] = { }, { - .name = SSL_TXT_kPSK, - .algorithm_mkey = SSL_kPSK, - }, - { - .name = SSL_TXT_kSRP, - .algorithm_mkey = SSL_kSRP, - }, - { .name = SSL_TXT_kGOST, .algorithm_mkey = SSL_kGOST, }, @@ -325,10 +312,6 @@ static const SSL_CIPHER cipher_aliases[] = { .algorithm_auth = SSL_aDSS, }, { - .name = SSL_TXT_aKRB5, - .algorithm_auth = SSL_aKRB5, - }, - { .name = SSL_TXT_aNULL, .algorithm_auth = SSL_aNULL, }, @@ -350,10 +333,6 @@ static const SSL_CIPHER cipher_aliases[] = { .algorithm_auth = SSL_aECDSA, }, { - .name = SSL_TXT_aPSK, - .algorithm_auth = SSL_aPSK, - }, - { .name = SSL_TXT_aGOST94, .algorithm_auth = SSL_aGOST94, }, @@ -382,11 +361,6 @@ static const SSL_CIPHER cipher_aliases[] = { .algorithm_enc = SSL_eNULL, }, { - .name = SSL_TXT_KRB5, - .algorithm_mkey = SSL_kKRB5, - .algorithm_auth = SSL_aKRB5, - }, - { .name = SSL_TXT_RSA, .algorithm_mkey = SSL_kRSA, .algorithm_auth = SSL_aRSA, @@ -401,16 +375,7 @@ static const SSL_CIPHER cipher_aliases[] = { .algorithm_mkey = SSL_kEECDH, .algorithm_auth = SSL_aNULL, }, - { - .name = SSL_TXT_PSK, - .algorithm_mkey = SSL_kPSK, - .algorithm_auth = SSL_aPSK, - }, - { - .name = SSL_TXT_SRP, - .algorithm_mkey = SSL_kSRP, - }, - + /* symmetric encryption aliases */ { .name = SSL_TXT_DES, @@ -881,11 +846,7 @@ ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, unsigned long *mkey |= SSL_kDHr|SSL_kDHd; /* no such ciphersuites supported! */ *auth |= SSL_aDH; - *mkey |= SSL_kKRB5; - *auth |= SSL_aKRB5; - *mkey |= SSL_kPSK; - *auth |= SSL_aPSK; - *mkey |= SSL_kSRP; + /* Check for presence of GOST 34.10 algorithms, and if they * do not present, disable appropriate auth and key exchange */ if (!get_optional_pkey_id("gost94")) { @@ -1515,8 +1476,6 @@ ssl_create_cipher_list(const SSL_METHOD *ssl_method, ssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); /* ssl_cipher_apply_rule(0, 0, SSL_aDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); */ ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); - ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); - ssl_cipher_apply_rule(0, SSL_kKRB5, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); /* RC4 is sort-of broken -- move the the end */ ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); @@ -1650,9 +1609,6 @@ SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_kDHd: kx = "DH/DSS"; break; - case SSL_kKRB5: - kx = "KRB5"; - break; case SSL_kEDH: kx = "DH"; break; @@ -1665,12 +1621,6 @@ SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_kEECDH: kx = "ECDH"; break; - case SSL_kPSK: - kx = "PSK"; - break; - case SSL_kSRP: - kx = "SRP"; - break; default: kx = "unknown"; } @@ -1685,9 +1635,6 @@ SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_aDH: au = "DH"; break; - case SSL_aKRB5: - au = "KRB5"; - break; case SSL_aECDH: au = "ECDH"; break; @@ -1697,9 +1644,6 @@ SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_aECDSA: au = "ECDSA"; break; - case SSL_aPSK: - au = "PSK"; - break; default: au = "unknown"; break; diff --git a/lib/libssl/ssl_lib.c b/lib/libssl/ssl_lib.c index c3169204f6c..beb8089475a 100644 --- a/lib/libssl/ssl_lib.c +++ b/lib/libssl/ssl_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_lib.c,v 1.74 2014/07/11 09:24:44 beck Exp $ */ +/* $OpenBSD: ssl_lib.c,v 1.75 2014/07/12 13:11:53 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -2137,9 +2137,6 @@ ssl_get_server_send_pkey(const SSL *s) i = SSL_PKEY_RSA_SIGN; else i = SSL_PKEY_RSA_ENC; - } else if (alg_a & SSL_aKRB5) { - /* VRS something else here? */ - return (NULL); } else if (alg_a & SSL_aGOST94) { i = SSL_PKEY_GOST94; } else if (alg_a & SSL_aGOST01) { diff --git a/lib/libssl/ssl_locl.h b/lib/libssl/ssl_locl.h index c1e402b3a13..0d96ee5fe8b 100644 --- a/lib/libssl/ssl_locl.h +++ b/lib/libssl/ssl_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_locl.h,v 1.59 2014/07/11 08:17:36 miod Exp $ */ +/* $OpenBSD: ssl_locl.h,v 1.60 2014/07/12 13:11:53 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -257,13 +257,10 @@ #define SSL_kDHr 0x00000002L /* DH cert, RSA CA cert */ /* no such ciphersuites supported! */ #define SSL_kDHd 0x00000004L /* DH cert, DSA CA cert */ /* no such ciphersuite supported! */ #define SSL_kEDH 0x00000008L /* tmp DH key no DH cert */ -#define SSL_kKRB5 0x00000010L /* Kerberos5 key exchange */ #define SSL_kECDHr 0x00000020L /* ECDH cert, RSA CA cert */ #define SSL_kECDHe 0x00000040L /* ECDH cert, ECDSA CA cert */ #define SSL_kEECDH 0x00000080L /* ephemeral ECDH */ -#define SSL_kPSK 0x00000100L /* PSK */ -#define SSL_kGOST 0x00000200L /* GOST key exchange */ -#define SSL_kSRP 0x00000400L /* SRP */ +#define SSL_kGOST 0x00000200L /* GOST key exchange */ /* Bits for algorithm_auth (server authentication) */ #define SSL_aRSA 0x00000001L /* RSA auth */ @@ -271,9 +268,7 @@ #define SSL_aNULL 0x00000004L /* no auth (i.e. use ADH or AECDH) */ #define SSL_aDH 0x00000008L /* Fixed DH auth (kDHd or kDHr) */ /* no such ciphersuites supported! */ #define SSL_aECDH 0x00000010L /* Fixed ECDH auth (kECDHe or kECDHr) */ -#define SSL_aKRB5 0x00000020L /* KRB5 auth */ #define SSL_aECDSA 0x00000040L /* ECDSA auth*/ -#define SSL_aPSK 0x00000080L /* PSK auth */ #define SSL_aGOST94 0x00000100L /* GOST R 34.10-94 signature auth */ #define SSL_aGOST01 0x00000200L /* GOST R 34.10-2001 signature auth */ |