1 diff -uNr openssh-4.5p1/authfd.h openssh-4.5p1-pkcs11forward/authfd.h 2 --- openssh-4.5p1/authfd.h 2021-11-13 13:16:54.394351755 -0600 3 +++ openssh-4.5p1-pkcs11forward/authfd.h 2014-11-19 13:09:24.311033000 -0600 4 @@ -56,6 +56,11 @@ 5 #define SSH_AGENTC_PKCS11_REMOVE_ID 29 6 #define SSH_AGENTC_PKCS11_SET_ASK_PIN 30 7 8 +#define SSH2_AGENTC_DECRYPT_REQUEST 70 9 +#define SSH2_AGENT_DECRYPT_RESPONSE 71 10 +#define SSH2_AGENTC_PKCS11_CERT_REQUEST 72 11 +#define SSH2_AGENT_PKCS11_CERT_RESPONSE 73 12 + 13 #define SSH_AGENT_CONSTRAIN_LIFETIME 1 14 #define SSH_AGENT_CONSTRAIN_CONFIRM 2 15 16 @@ -66,6 +71,7 @@ 17 #define SSH_COM_AGENT2_FAILURE 102 18 19 #define SSH_AGENT_OLD_SIGNATURE 0x01 20 +#define SSH_AGENT_SIGN_RAW 0x02 21 22 typedef struct { 23 int fd; 24 diff -uNr openssh-4.5p1/compat.h openssh-4.5p1-pkcs11forward/compat.h 25 --- openssh-4.5p1/compat.h 2006-03-25 21:30:01.000000000 -0600 26 +++ openssh-4.5p1-pkcs11forward/compat.h 2014-11-19 13:09:24.311033000 -0600 27 @@ -56,6 +56,7 @@ 28 #define SSH_BUG_PROBE 0x00400000 29 #define SSH_BUG_FIRSTKEX 0x00800000 30 #define SSH_OLD_FORWARD_ADDR 0x01000000 31 +#define SSH_BUG_SIGNRAW 0x02000000 32 33 void enable_compat13(void); 34 void enable_compat20(void); 35 diff -uNr openssh-4.5p1/pkcs11-helper.c openssh-4.5p1-pkcs11forward/pkcs11-helper.c 36 --- openssh-4.5p1/pkcs11-helper.c 2021-11-13 13:16:54.409351754 -0600 37 +++ openssh-4.5p1-pkcs11forward/pkcs11-helper.c 2014-11-19 13:09:24.371033000 -0600 38 @@ -1405,6 +1405,18 @@ 39 provider->handle = dlopen (provider_location, RTLD_NOW); 40 #endif 41 if (provider->handle == NULL) { 42 +#if defined(WIN32) 43 + PKCS11H_DEBUG ( 44 + PKCS11H_LOG_DEBUG2, 45 + "PKCS#11: pkcs11h_addProvider dlopen() failed." 46 + ); 47 +#else 48 + PKCS11H_DEBUG ( 49 + PKCS11H_LOG_DEBUG2, 50 + "PKCS#11: pkcs11h_addProvider dlopen() failed. error is %s", 51 + dlerror() 52 + ); 53 +#endif 54 rv = CKR_FUNCTION_FAILED; 55 } 56 } 57 @@ -1431,6 +1443,10 @@ 58 #endif 59 if (gfl == NULL) { 60 rv = CKR_FUNCTION_FAILED; 61 + PKCS11H_DEBUG ( 62 + PKCS11H_LOG_DEBUG2, 63 + "PKCS#11: pkcs11h_addProvider GetFunctionList missing." 64 + ); 65 } 66 } 67 68 @@ -3064,8 +3080,9 @@ 69 70 PKCS11H_DEBUG ( 71 PKCS11H_LOG_DEBUG2, 72 - "PKCS#11: _pkcs11h_session_findObjects entry session=%p, filter=%p, filter_attrs=%ld, p_objects=%p, p_objects_found=%p", 73 + "PKCS#11: _pkcs11h_session_findObjects entry session=%p, session(num)=%lu, filter=%p, filter_attrs=%ld, p_objects=%p, p_objects_found=%p", 74 (void *)session, 75 + (unsigned long) session->session_handle, 76 (void *)filter, 77 filter_attrs, 78 (void *)p_objects, 79 @@ -3084,6 +3101,12 @@ 80 )) == CKR_OK 81 ) { 82 should_FindObjectsFinal = TRUE; 83 + } else { 84 + PKCS11H_DEBUG ( 85 + PKCS11H_LOG_DEBUG2, 86 + "PKCS#11: _pkcs11h_session_findObjects: FindObjectsInit failed (handle = %lu)", 87 + (unsigned long) session->session_handle 88 + ); 89 } 90 91 while ( 92 @@ -9860,7 +9883,6 @@ 93 #else 94 session = (pkcs11h_openssl_session_t)RSA_get_app_data (rsa); 95 #endif 96 - PKCS11H_ASSERT (session!=NULL); 97 98 return session; 99 } 100 @@ -9871,10 +9893,11 @@ 101 IN OUT const RSA *rsa 102 ) { 103 pkcs11h_openssl_session_t session = _pkcs11h_openssl_get_openssl_session (rsa); 104 - 105 - PKCS11H_ASSERT (session!=NULL); 106 - PKCS11H_ASSERT (session->certificate!=NULL); 107 108 + if (!session) { 109 + return(NULL); 110 + } 111 + 112 return session->certificate; 113 } 114 115 @@ -9899,10 +9922,22 @@ 116 IN int padding 117 ) { 118 #endif 119 + pkcs11h_certificate_t certificate = _pkcs11h_openssl_get_pkcs11h_certificate (rsa); 120 + PKCS11H_BOOL session_locked = FALSE; 121 + CK_RV rv = CKR_OK; 122 + 123 + int myrsa_size = 0; 124 + size_t tolen = flen; 125 + 126 PKCS11H_ASSERT (from!=NULL); 127 PKCS11H_ASSERT (to!=NULL); 128 PKCS11H_ASSERT (rsa!=NULL); 129 130 + if (!certificate) { 131 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: No certificate available"); 132 + rv = CKR_GENERAL_ERROR; 133 + } 134 + 135 PKCS11H_DEBUG ( 136 PKCS11H_LOG_DEBUG2, 137 "PKCS#11: _pkcs11h_openssl_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d", 138 @@ -9913,17 +9948,57 @@ 139 padding 140 ); 141 142 - PKCS11H_LOG ( 143 - PKCS11H_LOG_ERROR, 144 - "PKCS#11: Private key decryption is not supported" 145 - ); 146 + if (rv == CKR_OK) { 147 + myrsa_size = RSA_size(rsa); 148 + } 149 + 150 + if ( 151 + rv == CKR_OK && 152 + flen != myrsa_size 153 + ) { 154 + rv = CKR_KEY_SIZE_RANGE; 155 + } 156 + 157 + if ( 158 + rv == CKR_OK && 159 + (rv = pkcs11h_certificate_lockSession (certificate)) == CKR_OK 160 + ) { 161 + session_locked = TRUE; 162 + } 163 + 164 + if (rv == CKR_OK) { 165 + PKCS11H_DEBUG ( 166 + PKCS11H_LOG_DEBUG1, 167 + "PKCS#11: Performing decryption" 168 + ); 169 + 170 + tolen = myrsa_size; 171 + 172 + if ( 173 + (rv = pkcs11h_certificate_decrypt( 174 + certificate, 175 + CKM_RSA_PKCS, 176 + from, 177 + flen, 178 + to, 179 + &tolen 180 + )) != CKR_OK 181 + ) { 182 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform decryption %ld:'%s'", rv, pkcs11h_getMessage (rv)); 183 + } 184 + } 185 + 186 + if (session_locked) { 187 + pkcs11h_certificate_releaseSession (certificate); 188 + session_locked = FALSE; 189 + } 190 191 PKCS11H_DEBUG ( 192 PKCS11H_LOG_DEBUG2, 193 - "PKCS#11: _pkcs11h_openssl_dec return" 194 + "PKCS#11: _pkcs11h_openssl_dec return: %i", (rv == CKR_OK ? ((int) tolen) : -1) 195 ); 196 197 - return -1; 198 + return rv == CKR_OK ? ((int) tolen) : -1; 199 } 200 201 #if OPENSSL_VERSION_NUMBER < 0x00907000L 202 @@ -10148,6 +10223,94 @@ 203 } 204 205 X509 * 206 +pkcs11h_openssl_getX509_fromRSA ( 207 + IN const RSA *rsa 208 +) { 209 + pkcs11h_certificate_t certificate = _pkcs11h_openssl_get_pkcs11h_certificate (rsa); 210 + unsigned char *certificate_blob = NULL; 211 + size_t certificate_blob_size = 0; 212 + X509 *x509 = NULL; 213 + CK_RV rv = CKR_OK; 214 + 215 + pkcs11_openssl_d2i_t d2i1 = NULL; 216 + PKCS11H_BOOL ok = TRUE; 217 + 218 + if (!certificate) { 219 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Certificate not available"); 220 + 221 + return(NULL); 222 + } 223 + 224 + PKCS11H_DEBUG ( 225 + PKCS11H_LOG_DEBUG2, 226 + "PKCS#11: pkcs11h_openssl_getX509 - entry certificate=%p", 227 + (void *)certificate 228 + ); 229 + 230 + if ( 231 + ok && 232 + (x509 = X509_new ()) == NULL 233 + ) { 234 + ok = FALSE; 235 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to allocate certificate object"); 236 + } 237 + 238 + if ( 239 + ok && 240 + pkcs11h_certificate_getCertificateBlob ( 241 + certificate, 242 + NULL, 243 + &certificate_blob_size 244 + ) != CKR_OK 245 + ) { 246 + ok = FALSE; 247 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11h_getMessage (rv)); 248 + } 249 + 250 + if ( 251 + ok && 252 + (rv = _pkcs11h_mem_malloc ((void *)&certificate_blob, certificate_blob_size)) != CKR_OK 253 + ) { 254 + ok = FALSE; 255 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate X.509 memory %ld-'%s'", rv, pkcs11h_getMessage (rv)); 256 + } 257 + 258 + if ( 259 + ok && 260 + pkcs11h_certificate_getCertificateBlob ( 261 + certificate, 262 + certificate_blob, 263 + &certificate_blob_size 264 + ) != CKR_OK 265 + ) { 266 + ok = FALSE; 267 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11h_getMessage (rv)); 268 + } 269 + 270 + d2i1 = (pkcs11_openssl_d2i_t)certificate_blob; 271 + if ( 272 + ok && 273 + !d2i_X509 (&x509, &d2i1, certificate_blob_size) 274 + ) { 275 + ok = FALSE; 276 + PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to parse X.509 certificate"); 277 + } 278 + 279 + if (!ok) { 280 + X509_free (x509); 281 + x509 = NULL; 282 + } 283 + 284 + PKCS11H_DEBUG ( 285 + PKCS11H_LOG_DEBUG2, 286 + "PKCS#11: pkcs11h_openssl_getX509 - return x509=%p", 287 + (void *)x509 288 + ); 289 + 290 + return x509; 291 +} 292 + 293 +X509 * 294 pkcs11h_openssl_getX509 ( 295 IN const pkcs11h_certificate_t certificate 296 ) { 297 diff -uNr openssh-4.5p1/pkcs11-helper.h openssh-4.5p1-pkcs11forward/pkcs11-helper.h 298 --- openssh-4.5p1/pkcs11-helper.h 2021-11-13 13:16:54.411351754 -0600 299 +++ openssh-4.5p1-pkcs11forward/pkcs11-helper.h 2014-11-19 13:09:24.371033000 -0600 300 @@ -1189,6 +1189,17 @@ 301 *======================================================================*/ 302 303 /* 304 + * pkcs11h_openssl_getX509_fromRSA - Returns an X509 object out of the openssl_session object. 305 + * 306 + * Parameters: 307 + * RSA - RSA blob 308 + */ 309 +X509 * 310 +pkcs11h_openssl_getX509_fromRSA ( 311 + IN const RSA *rsa 312 +); 313 + 314 +/* 315 * pkcs11h_openssl_getX509 - Returns an X509 object out of the openssl_session object. 316 * 317 * Parameters: 318 diff -uNr openssh-4.5p1/ssh-agent.c openssh-4.5p1-pkcs11forward/ssh-agent.c 319 --- openssh-4.5p1/ssh-agent.c 2021-11-13 13:16:54.412351754 -0600 320 +++ openssh-4.5p1-pkcs11forward/ssh-agent.c 2014-11-19 13:09:24.401033000 -0600 321 @@ -51,6 +51,7 @@ 322 323 #include <openssl/evp.h> 324 #include <openssl/md5.h> 325 +#include <openssl/err.h> 326 327 #include <errno.h> 328 #include <fcntl.h> 329 @@ -324,6 +325,10 @@ 330 if (flags & SSH_AGENT_OLD_SIGNATURE) 331 datafellows = SSH_BUG_SIGBLOB; 332 333 + /* Request that the data not be hashed, but instead just encrypted as it is */ 334 + if (flags & SSH_AGENT_SIGN_RAW) 335 + datafellows = SSH_BUG_SIGNRAW; 336 + 337 key = key_from_blob(blob, blen); 338 if (key != NULL) { 339 Identity *id = lookup_identity(key, 2); 340 @@ -693,6 +698,159 @@ 341 342 #ifndef SSH_PKCS11_DISABLED 343 344 + 345 + 346 + 347 +/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 decryption) */ 348 +static int 349 +ssh_rsa_decrypt(const Key *key, u_char **bufp, u_int *lenp, 350 + const u_char *data, u_int datalen) 351 +{ 352 + u_char *buf; 353 + u_int blen, len; 354 + int dlen; 355 + Buffer b; 356 + 357 + if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) { 358 + error("ssh_rsa_decrypt: no RSA key"); 359 + return -1; 360 + } 361 + 362 + blen = RSA_size(key->rsa); 363 + buf = xmalloc(blen); 364 + 365 + dlen = RSA_private_decrypt(datalen, data, buf, key->rsa, RSA_PKCS1_PADDING); 366 + 367 + if (dlen < 0) { 368 + int ecode = ERR_get_error(); 369 + 370 + error("ssh_rsa_decrypt: RSA_private_decrypt failed: %s", 371 + ERR_error_string(ecode, NULL)); 372 + xfree(buf); 373 + return -1; 374 + } 375 + 376 + /* encode plaintext */ 377 + buffer_init(&b); 378 + buffer_put_string(&b, buf, dlen); 379 + len = buffer_len(&b); 380 + 381 + if (lenp != NULL) 382 + *lenp = len; 383 + if (bufp != NULL) { 384 + *bufp = xmalloc(len); 385 + memcpy(*bufp, buffer_ptr(&b), len); 386 + } 387 + 388 + buffer_free(&b); 389 + 390 + memset(buf, 's', dlen); 391 + xfree(buf); 392 + 393 + return 0; 394 +} 395 + 396 +static void 397 +process_decrypt_request2(SocketEntry *e) 398 +{ 399 + u_char *blob, *data, *plaintext = NULL; 400 + u_int blen, dlen, plen = 0; 401 + extern int datafellows; 402 + int ok = -1, flags; 403 + Buffer msg; 404 + Key *key; 405 + 406 + datafellows = 0; 407 + 408 + blob = buffer_get_string(&e->request, &blen); 409 + data = buffer_get_string(&e->request, &dlen); 410 + 411 + flags = buffer_get_int(&e->request); 412 + 413 + key = key_from_blob(blob, blen); 414 + if (key != NULL) { 415 + Identity *id = lookup_identity(key, 2); 416 + 417 + if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { 418 + ok = ssh_rsa_decrypt(id->key, &plaintext, &plen, data, dlen); 419 + } 420 + 421 + key_free(key); 422 + } 423 + buffer_init(&msg); 424 + if (ok == 0) { 425 + buffer_put_char(&msg, SSH2_AGENT_DECRYPT_RESPONSE); 426 + buffer_put_string(&msg, plaintext, plen); 427 + } else { 428 + buffer_put_char(&msg, SSH_AGENT_FAILURE); 429 + } 430 + buffer_put_int(&e->output, buffer_len(&msg)); 431 + buffer_append(&e->output, buffer_ptr(&msg), 432 + buffer_len(&msg)); 433 + buffer_free(&msg); 434 + xfree(data); 435 + xfree(blob); 436 + if (plaintext != NULL) 437 + xfree(plaintext); 438 +} 439 + 440 +#include <openssl/x509.h> 441 +#include "pkcs11-helper.h" 442 + 443 +static void 444 +process_cert_request2(SocketEntry *e) 445 +{ 446 + u_char *blob, *cert_der, *temp; 447 + u_int blen; 448 + extern int datafellows; 449 + Buffer msg; 450 + Key *key; 451 + X509 *cert_i; 452 + int cert_derlen, ok = 0; 453 + 454 + datafellows = 0; 455 + 456 + blob = buffer_get_string(&e->request, &blen); 457 + 458 + buffer_init(&msg); 459 + 460 + key = key_from_blob(blob, blen); 461 + if (key != NULL) { 462 + Identity *id = lookup_identity(key, 2); 463 + if (id != NULL && id->key != NULL && id->key->rsa != NULL) { 464 + cert_i = pkcs11h_openssl_getX509_fromRSA(id->key->rsa); 465 + 466 + cert_derlen = i2d_X509(cert_i, NULL); 467 + cert_der = OPENSSL_malloc(cert_derlen); 468 + if (cert_der) { 469 + temp = cert_der; 470 + cert_derlen = i2d_X509(cert_i, &temp); 471 + 472 + /* Encode response */ 473 + buffer_put_char(&msg, SSH2_AGENT_PKCS11_CERT_RESPONSE); 474 + buffer_put_string(&msg, cert_der, cert_derlen); 475 + 476 + ok = 1; 477 + 478 + OPENSSL_free(cert_der); 479 + } 480 + } 481 + } 482 + 483 + if (!ok) { 484 + /* Encode error */ 485 + buffer_put_char(&msg, SSH_AGENT_FAILURE); 486 + } 487 + 488 + /* Send value */ 489 + buffer_put_int(&e->output, buffer_len(&msg)); 490 + buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); 491 + buffer_free(&msg); 492 + xfree(blob); 493 + 494 + return; 495 +} 496 + 497 static 498 void 499 process_pkcs11_set_ask_pin (SocketEntry *e) 500 @@ -951,6 +1109,12 @@ 501 case SSH_AGENTC_PKCS11_REMOVE_ID: 502 process_pkcs11_remove_id (e); 503 break; 504 + case SSH2_AGENTC_DECRYPT_REQUEST: 505 + process_decrypt_request2(e); 506 + break; 507 + case SSH2_AGENTC_PKCS11_CERT_REQUEST: 508 + process_cert_request2(e); 509 + break; 510 #endif /* SSH_PKCS11_DISABLED */ 511 default: 512 /* Unknown message. Respond with failure. */ 513 diff -uNr openssh-4.5p1/ssh-rsa.c openssh-4.5p1-pkcs11forward/ssh-rsa.c 514 --- openssh-4.5p1/ssh-rsa.c 2006-09-01 00:38:37.000000000 -0500 515 +++ openssh-4.5p1-pkcs11forward/ssh-rsa.c 2014-11-19 13:09:24.411033000 -0600 516 @@ -50,20 +50,27 @@ 517 error("ssh_rsa_sign: no RSA key"); 518 return -1; 519 } 520 - nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; 521 - if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { 522 - error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid); 523 - return -1; 524 - } 525 - EVP_DigestInit(&md, evp_md); 526 - EVP_DigestUpdate(&md, data, datalen); 527 - EVP_DigestFinal(&md, digest, &dlen); 528 529 slen = RSA_size(key->rsa); 530 sig = xmalloc(slen); 531 532 - ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa); 533 - memset(digest, 'd', sizeof(digest)); 534 + if ((datafellows & SSH_BUG_SIGNRAW) != SSH_BUG_SIGNRAW) { 535 + nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; 536 + if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { 537 + error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid); 538 + return -1; 539 + } 540 + EVP_DigestInit(&md, evp_md); 541 + EVP_DigestUpdate(&md, data, datalen); 542 + EVP_DigestFinal(&md, digest, &dlen); 543 + 544 + ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa); 545 + memset(digest, 'd', sizeof(digest)); 546 + } else { 547 + nid = NID_md5_sha1; 548 + 549 + ok = RSA_sign(nid, data, datalen, sig, &len, key->rsa); 550 + } 551 552 if (ok != 1) { 553 int ecode = ERR_get_error(); |