1 // Copyright 2013 Miek Gieben. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:generate go run const_generate.go 6 7 // Package pkcs11 is a wrapper around the PKCS#11 cryptographic library. 8 package pkcs11 9 10 // It is *assumed*, that: 11 // 12 // * Go's uint size == PKCS11's CK_ULONG size 13 // * CK_ULONG never overflows an Go int 14 15 /* 16 #cgo windows CFLAGS: -DPACKED_STRUCTURES 17 #cgo linux LDFLAGS: -ldl 18 #cgo darwin LDFLAGS: -ldl 19 #cgo openbsd LDFLAGS: 20 #cgo freebsd LDFLAGS: -ldl 21 22 #include <stdlib.h> 23 #include <stdio.h> 24 #include <string.h> 25 #include <unistd.h> 26 27 #include "pkcs11go.h" 28 29 #ifdef _WIN32 30 #include <windows.h> 31 32 struct ctx { 33 HMODULE handle; 34 CK_FUNCTION_LIST_PTR sym; 35 }; 36 37 // New initializes a ctx and fills the symbol table. 38 struct ctx *New(const char *module) 39 { 40 CK_C_GetFunctionList list; 41 struct ctx *c = calloc(1, sizeof(struct ctx)); 42 c->handle = LoadLibrary(module); 43 if (c->handle == NULL) { 44 free(c); 45 return NULL; 46 } 47 list = (CK_C_GetFunctionList) GetProcAddress(c->handle, "C_GetFunctionList"); 48 if (list == NULL) { 49 free(c); 50 return NULL; 51 } 52 list(&c->sym); 53 return c; 54 } 55 56 // Destroy cleans up a ctx. 57 void Destroy(struct ctx *c) 58 { 59 if (!c) { 60 return; 61 } 62 free(c); 63 } 64 #else 65 #include <dlfcn.h> 66 67 struct ctx { 68 void *handle; 69 CK_FUNCTION_LIST_PTR sym; 70 }; 71 72 // New initializes a ctx and fills the symbol table. 73 struct ctx *New(const char *module) 74 { 75 CK_C_GetFunctionList list; 76 struct ctx *c = calloc(1, sizeof(struct ctx)); 77 c->handle = dlopen(module, RTLD_LAZY); 78 if (c->handle == NULL) { 79 free(c); 80 return NULL; 81 } 82 list = (CK_C_GetFunctionList) dlsym(c->handle, "C_GetFunctionList"); 83 if (list == NULL) { 84 free(c); 85 return NULL; 86 } 87 list(&c->sym); 88 return c; 89 } 90 91 // Destroy cleans up a ctx. 92 void Destroy(struct ctx *c) 93 { 94 if (!c) { 95 return; 96 } 97 if (c->handle == NULL) { 98 return; 99 } 100 if (dlclose(c->handle) < 0) { 101 return; 102 } 103 free(c); 104 } 105 #endif 106 107 CK_RV Initialize(struct ctx * c) 108 { 109 CK_C_INITIALIZE_ARGS args; 110 memset(&args, 0, sizeof(args)); 111 args.flags = CKF_OS_LOCKING_OK; 112 return c->sym->C_Initialize(&args); 113 } 114 115 CK_RV Finalize(struct ctx * c) 116 { 117 return c->sym->C_Finalize(NULL); 118 } 119 120 CK_RV GetInfo(struct ctx * c, ckInfoPtr info) 121 { 122 CK_INFO p; 123 CK_RV e = c->sym->C_GetInfo(&p); 124 if (e != CKR_OK) { 125 return e; 126 } 127 info->cryptokiVersion = p.cryptokiVersion; 128 memcpy(info->manufacturerID, p.manufacturerID, sizeof(p.manufacturerID)); 129 info->flags = p.flags; 130 memcpy(info->libraryDescription, p.libraryDescription, sizeof(p.libraryDescription)); 131 info->libraryVersion = p.libraryVersion; 132 return e; 133 } 134 135 CK_RV GetSlotList(struct ctx * c, CK_BBOOL tokenPresent, 136 CK_ULONG_PTR * slotList, CK_ULONG_PTR ulCount) 137 { 138 CK_RV e = c->sym->C_GetSlotList(tokenPresent, NULL, ulCount); 139 if (e != CKR_OK) { 140 return e; 141 } 142 *slotList = calloc(*ulCount, sizeof(CK_SLOT_ID)); 143 e = c->sym->C_GetSlotList(tokenPresent, *slotList, ulCount); 144 return e; 145 } 146 147 CK_RV GetSlotInfo(struct ctx * c, CK_ULONG slotID, CK_SLOT_INFO_PTR info) 148 { 149 CK_RV e = c->sym->C_GetSlotInfo((CK_SLOT_ID) slotID, info); 150 return e; 151 } 152 153 CK_RV GetTokenInfo(struct ctx * c, CK_ULONG slotID, CK_TOKEN_INFO_PTR info) 154 { 155 CK_RV e = c->sym->C_GetTokenInfo((CK_SLOT_ID) slotID, info); 156 return e; 157 } 158 159 CK_RV GetMechanismList(struct ctx * c, CK_ULONG slotID, 160 CK_ULONG_PTR * mech, CK_ULONG_PTR mechlen) 161 { 162 CK_RV e = 163 c->sym->C_GetMechanismList((CK_SLOT_ID) slotID, NULL, mechlen); 164 // Gemaltos PKCS11 implementation returns CKR_BUFFER_TOO_SMALL on a NULL ptr instad of CKR_OK as the spec states. 165 if (e != CKR_OK && e != CKR_BUFFER_TOO_SMALL) { 166 return e; 167 } 168 *mech = calloc(*mechlen, sizeof(CK_MECHANISM_TYPE)); 169 e = c->sym->C_GetMechanismList((CK_SLOT_ID) slotID, 170 (CK_MECHANISM_TYPE_PTR) * mech, mechlen); 171 return e; 172 } 173 174 CK_RV GetMechanismInfo(struct ctx * c, CK_ULONG slotID, CK_MECHANISM_TYPE mech, 175 CK_MECHANISM_INFO_PTR info) 176 { 177 CK_RV e = c->sym->C_GetMechanismInfo((CK_SLOT_ID) slotID, mech, info); 178 return e; 179 } 180 181 CK_RV InitToken(struct ctx * c, CK_ULONG slotID, char *pin, CK_ULONG pinlen, 182 char *label) 183 { 184 CK_RV e = 185 c->sym->C_InitToken((CK_SLOT_ID) slotID, (CK_UTF8CHAR_PTR) pin, 186 pinlen, (CK_UTF8CHAR_PTR) label); 187 return e; 188 } 189 190 CK_RV InitPIN(struct ctx * c, CK_SESSION_HANDLE sh, char *pin, CK_ULONG pinlen) 191 { 192 CK_RV e = c->sym->C_InitPIN(sh, (CK_UTF8CHAR_PTR) pin, pinlen); 193 return e; 194 } 195 196 CK_RV SetPIN(struct ctx * c, CK_SESSION_HANDLE sh, char *oldpin, 197 CK_ULONG oldpinlen, char *newpin, CK_ULONG newpinlen) 198 { 199 CK_RV e = c->sym->C_SetPIN(sh, (CK_UTF8CHAR_PTR) oldpin, oldpinlen, 200 (CK_UTF8CHAR_PTR) newpin, newpinlen); 201 return e; 202 } 203 204 CK_RV OpenSession(struct ctx * c, CK_ULONG slotID, CK_ULONG flags, 205 CK_SESSION_HANDLE_PTR session) 206 { 207 CK_RV e = 208 c->sym->C_OpenSession((CK_SLOT_ID) slotID, (CK_FLAGS) flags, NULL, 209 NULL, session); 210 return e; 211 } 212 213 CK_RV CloseSession(struct ctx * c, CK_SESSION_HANDLE session) 214 { 215 CK_RV e = c->sym->C_CloseSession(session); 216 return e; 217 } 218 219 CK_RV CloseAllSessions(struct ctx * c, CK_ULONG slotID) 220 { 221 CK_RV e = c->sym->C_CloseAllSessions(slotID); 222 return e; 223 } 224 225 CK_RV GetSessionInfo(struct ctx * c, CK_SESSION_HANDLE session, 226 CK_SESSION_INFO_PTR info) 227 { 228 CK_RV e = c->sym->C_GetSessionInfo(session, info); 229 return e; 230 } 231 232 CK_RV GetOperationState(struct ctx * c, CK_SESSION_HANDLE session, 233 CK_BYTE_PTR * state, CK_ULONG_PTR statelen) 234 { 235 CK_RV rv = c->sym->C_GetOperationState(session, NULL, statelen); 236 if (rv != CKR_OK) { 237 return rv; 238 } 239 *state = calloc(*statelen, sizeof(CK_BYTE)); 240 if (*state == NULL) { 241 return CKR_HOST_MEMORY; 242 } 243 rv = c->sym->C_GetOperationState(session, *state, statelen); 244 return rv; 245 } 246 247 CK_RV SetOperationState(struct ctx * c, CK_SESSION_HANDLE session, 248 CK_BYTE_PTR state, CK_ULONG statelen, 249 CK_OBJECT_HANDLE encryptkey, CK_OBJECT_HANDLE authkey) 250 { 251 return c->sym->C_SetOperationState(session, state, statelen, encryptkey, 252 authkey); 253 } 254 255 CK_RV Login(struct ctx *c, CK_SESSION_HANDLE session, CK_USER_TYPE userType, 256 char *pin, CK_ULONG pinLen) 257 { 258 if (pinLen == 0) { 259 pin = NULL; 260 } 261 CK_RV e = 262 c->sym->C_Login(session, userType, (CK_UTF8CHAR_PTR) pin, pinLen); 263 return e; 264 } 265 266 CK_RV Logout(struct ctx * c, CK_SESSION_HANDLE session) 267 { 268 CK_RV e = c->sym->C_Logout(session); 269 return e; 270 } 271 272 CK_RV CreateObject(struct ctx * c, CK_SESSION_HANDLE session, 273 CK_ATTRIBUTE_PTR temp, CK_ULONG tempCount, 274 CK_OBJECT_HANDLE_PTR obj) 275 { 276 return c->sym->C_CreateObject(session, temp, tempCount, obj); 277 } 278 279 CK_RV CopyObject(struct ctx * c, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o, 280 CK_ATTRIBUTE_PTR temp, CK_ULONG tempCount, 281 CK_OBJECT_HANDLE_PTR obj) 282 { 283 return c->sym->C_CopyObject(session, o, temp, tempCount, obj); 284 } 285 286 CK_RV DestroyObject(struct ctx * c, CK_SESSION_HANDLE session, 287 CK_OBJECT_HANDLE object) 288 { 289 CK_RV e = c->sym->C_DestroyObject(session, object); 290 return e; 291 } 292 293 CK_RV GetObjectSize(struct ctx * c, CK_SESSION_HANDLE session, 294 CK_OBJECT_HANDLE object, CK_ULONG_PTR size) 295 { 296 CK_RV e = c->sym->C_GetObjectSize(session, object, size); 297 return e; 298 } 299 300 CK_RV GetAttributeValue(struct ctx * c, CK_SESSION_HANDLE session, 301 CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR temp, 302 CK_ULONG templen) 303 { 304 // Call for the first time, check the returned ulValue in the attributes, then 305 // allocate enough space and try again. 306 CK_RV e = c->sym->C_GetAttributeValue(session, object, temp, templen); 307 if (e != CKR_OK) { 308 return e; 309 } 310 CK_ULONG i; 311 for (i = 0; i < templen; i++) { 312 if ((CK_LONG) temp[i].ulValueLen == -1) { 313 // either access denied or no such object 314 continue; 315 } 316 temp[i].pValue = calloc(temp[i].ulValueLen, sizeof(CK_BYTE)); 317 } 318 return c->sym->C_GetAttributeValue(session, object, temp, templen); 319 } 320 321 CK_RV SetAttributeValue(struct ctx * c, CK_SESSION_HANDLE session, 322 CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR temp, 323 CK_ULONG templen) 324 { 325 return c->sym->C_SetAttributeValue(session, object, temp, templen); 326 } 327 328 CK_RV FindObjectsInit(struct ctx * c, CK_SESSION_HANDLE session, 329 CK_ATTRIBUTE_PTR temp, CK_ULONG tempCount) 330 { 331 return c->sym->C_FindObjectsInit(session, temp, tempCount); 332 } 333 334 CK_RV FindObjects(struct ctx * c, CK_SESSION_HANDLE session, 335 CK_OBJECT_HANDLE_PTR * obj, CK_ULONG max, 336 CK_ULONG_PTR objCount) 337 { 338 *obj = calloc(max, sizeof(CK_OBJECT_HANDLE)); 339 CK_RV e = c->sym->C_FindObjects(session, *obj, max, objCount); 340 return e; 341 } 342 343 CK_RV FindObjectsFinal(struct ctx * c, CK_SESSION_HANDLE session) 344 { 345 CK_RV e = c->sym->C_FindObjectsFinal(session); 346 return e; 347 } 348 349 CK_RV EncryptInit(struct ctx * c, CK_SESSION_HANDLE session, 350 CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) 351 { 352 return c->sym->C_EncryptInit(session, mechanism, key); 353 } 354 355 CK_RV Encrypt(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR message, 356 CK_ULONG mlen, CK_BYTE_PTR * enc, CK_ULONG_PTR enclen) 357 { 358 CK_RV rv = c->sym->C_Encrypt(session, message, mlen, NULL, enclen); 359 if (rv != CKR_OK) { 360 return rv; 361 } 362 *enc = calloc(*enclen, sizeof(CK_BYTE)); 363 if (*enc == NULL) { 364 return CKR_HOST_MEMORY; 365 } 366 rv = c->sym->C_Encrypt(session, message, mlen, *enc, enclen); 367 return rv; 368 } 369 370 CK_RV EncryptUpdate(struct ctx * c, CK_SESSION_HANDLE session, 371 CK_BYTE_PTR plain, CK_ULONG plainlen, CK_BYTE_PTR * cipher, 372 CK_ULONG_PTR cipherlen) 373 { 374 CK_RV rv = 375 c->sym->C_EncryptUpdate(session, plain, plainlen, NULL, cipherlen); 376 if (rv != CKR_OK) { 377 return rv; 378 } 379 *cipher = calloc(*cipherlen, sizeof(CK_BYTE)); 380 if (*cipher == NULL) { 381 return CKR_HOST_MEMORY; 382 } 383 rv = c->sym->C_EncryptUpdate(session, plain, plainlen, *cipher, 384 cipherlen); 385 return rv; 386 } 387 388 CK_RV EncryptFinal(struct ctx * c, CK_SESSION_HANDLE session, 389 CK_BYTE_PTR * cipher, CK_ULONG_PTR cipherlen) 390 { 391 CK_RV rv = c->sym->C_EncryptFinal(session, NULL, cipherlen); 392 if (rv != CKR_OK) { 393 return rv; 394 } 395 *cipher = calloc(*cipherlen, sizeof(CK_BYTE)); 396 if (*cipher == NULL) { 397 return CKR_HOST_MEMORY; 398 } 399 rv = c->sym->C_EncryptFinal(session, *cipher, cipherlen); 400 return rv; 401 } 402 403 CK_RV DecryptInit(struct ctx * c, CK_SESSION_HANDLE session, 404 CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) 405 { 406 return c->sym->C_DecryptInit(session, mechanism, key); 407 } 408 409 CK_RV Decrypt(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR cipher, 410 CK_ULONG clen, CK_BYTE_PTR * plain, CK_ULONG_PTR plainlen) 411 { 412 CK_RV e = c->sym->C_Decrypt(session, cipher, clen, NULL, plainlen); 413 if (e != CKR_OK) { 414 return e; 415 } 416 *plain = calloc(*plainlen, sizeof(CK_BYTE)); 417 if (*plain == NULL) { 418 return CKR_HOST_MEMORY; 419 } 420 e = c->sym->C_Decrypt(session, cipher, clen, *plain, plainlen); 421 return e; 422 } 423 424 CK_RV DecryptUpdate(struct ctx * c, CK_SESSION_HANDLE session, 425 CK_BYTE_PTR cipher, CK_ULONG cipherlen, CK_BYTE_PTR * part, 426 CK_ULONG_PTR partlen) 427 { 428 CK_RV rv = 429 c->sym->C_DecryptUpdate(session, cipher, cipherlen, NULL, partlen); 430 if (rv != CKR_OK) { 431 return rv; 432 } 433 *part = calloc(*partlen, sizeof(CK_BYTE)); 434 if (*part == NULL) { 435 return CKR_HOST_MEMORY; 436 } 437 rv = c->sym->C_DecryptUpdate(session, cipher, cipherlen, *part, 438 partlen); 439 return rv; 440 } 441 442 CK_RV DecryptFinal(struct ctx * c, CK_SESSION_HANDLE session, 443 CK_BYTE_PTR * plain, CK_ULONG_PTR plainlen) 444 { 445 CK_RV rv = c->sym->C_DecryptFinal(session, NULL, plainlen); 446 if (rv != CKR_OK) { 447 return rv; 448 } 449 *plain = calloc(*plainlen, sizeof(CK_BYTE)); 450 if (*plain == NULL) { 451 return CKR_HOST_MEMORY; 452 } 453 rv = c->sym->C_DecryptFinal(session, *plain, plainlen); 454 return rv; 455 } 456 457 CK_RV DigestInit(struct ctx * c, CK_SESSION_HANDLE session, 458 CK_MECHANISM_PTR mechanism) 459 { 460 return c->sym->C_DigestInit(session, mechanism); 461 } 462 463 CK_RV Digest(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR message, 464 CK_ULONG mlen, CK_BYTE_PTR * hash, CK_ULONG_PTR hashlen) 465 { 466 CK_RV rv = c->sym->C_Digest(session, message, mlen, NULL, hashlen); 467 if (rv != CKR_OK) { 468 return rv; 469 } 470 *hash = calloc(*hashlen, sizeof(CK_BYTE)); 471 if (*hash == NULL) { 472 return CKR_HOST_MEMORY; 473 } 474 rv = c->sym->C_Digest(session, message, mlen, *hash, hashlen); 475 return rv; 476 } 477 478 CK_RV DigestUpdate(struct ctx * c, CK_SESSION_HANDLE session, 479 CK_BYTE_PTR message, CK_ULONG mlen) 480 { 481 CK_RV rv = c->sym->C_DigestUpdate(session, message, mlen); 482 return rv; 483 } 484 485 CK_RV DigestKey(struct ctx * c, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) 486 { 487 CK_RV rv = c->sym->C_DigestKey(session, key); 488 return rv; 489 } 490 491 CK_RV DigestFinal(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR * hash, 492 CK_ULONG_PTR hashlen) 493 { 494 CK_RV rv = c->sym->C_DigestFinal(session, NULL, hashlen); 495 if (rv != CKR_OK) { 496 return rv; 497 } 498 *hash = calloc(*hashlen, sizeof(CK_BYTE)); 499 if (*hash == NULL) { 500 return CKR_HOST_MEMORY; 501 } 502 rv = c->sym->C_DigestFinal(session, *hash, hashlen); 503 return rv; 504 } 505 506 CK_RV SignInit(struct ctx * c, CK_SESSION_HANDLE session, 507 CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) 508 { 509 return c->sym->C_SignInit(session, mechanism, key); 510 } 511 512 CK_RV Sign(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR message, 513 CK_ULONG mlen, CK_BYTE_PTR * sig, CK_ULONG_PTR siglen) 514 { 515 CK_RV rv = c->sym->C_Sign(session, message, mlen, NULL, siglen); 516 if (rv != CKR_OK) { 517 return rv; 518 } 519 *sig = calloc(*siglen, sizeof(CK_BYTE)); 520 if (*sig == NULL) { 521 return CKR_HOST_MEMORY; 522 } 523 rv = c->sym->C_Sign(session, message, mlen, *sig, siglen); 524 return rv; 525 } 526 527 CK_RV SignUpdate(struct ctx * c, CK_SESSION_HANDLE session, 528 CK_BYTE_PTR message, CK_ULONG mlen) 529 { 530 CK_RV rv = c->sym->C_SignUpdate(session, message, mlen); 531 return rv; 532 } 533 534 CK_RV SignFinal(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR * sig, 535 CK_ULONG_PTR siglen) 536 { 537 CK_RV rv = c->sym->C_SignFinal(session, NULL, siglen); 538 if (rv != CKR_OK) { 539 return rv; 540 } 541 *sig = calloc(*siglen, sizeof(CK_BYTE)); 542 if (*sig == NULL) { 543 return CKR_HOST_MEMORY; 544 } 545 rv = c->sym->C_SignFinal(session, *sig, siglen); 546 return rv; 547 } 548 549 CK_RV SignRecoverInit(struct ctx * c, CK_SESSION_HANDLE session, 550 CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) 551 { 552 return c->sym->C_SignRecoverInit(session, mechanism, key); 553 } 554 555 CK_RV SignRecover(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR data, 556 CK_ULONG datalen, CK_BYTE_PTR * sig, CK_ULONG_PTR siglen) 557 { 558 CK_RV rv = c->sym->C_SignRecover(session, data, datalen, NULL, siglen); 559 if (rv != CKR_OK) { 560 return rv; 561 } 562 *sig = calloc(*siglen, sizeof(CK_BYTE)); 563 if (*sig == NULL) { 564 return CKR_HOST_MEMORY; 565 } 566 rv = c->sym->C_SignRecover(session, data, datalen, *sig, siglen); 567 return rv; 568 } 569 570 CK_RV VerifyInit(struct ctx * c, CK_SESSION_HANDLE session, 571 CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) 572 { 573 return c->sym->C_VerifyInit(session, mechanism, key); 574 } 575 576 CK_RV Verify(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR message, 577 CK_ULONG mesglen, CK_BYTE_PTR sig, CK_ULONG siglen) 578 { 579 CK_RV rv = c->sym->C_Verify(session, message, mesglen, sig, siglen); 580 return rv; 581 } 582 583 CK_RV VerifyUpdate(struct ctx * c, CK_SESSION_HANDLE session, 584 CK_BYTE_PTR part, CK_ULONG partlen) 585 { 586 CK_RV rv = c->sym->C_VerifyUpdate(session, part, partlen); 587 return rv; 588 } 589 590 CK_RV VerifyFinal(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR sig, 591 CK_ULONG siglen) 592 { 593 CK_RV rv = c->sym->C_VerifyFinal(session, sig, siglen); 594 return rv; 595 } 596 597 CK_RV VerifyRecoverInit(struct ctx * c, CK_SESSION_HANDLE session, 598 CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) 599 { 600 return c->sym->C_VerifyRecoverInit(session, mechanism, key); 601 } 602 603 CK_RV VerifyRecover(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR sig, 604 CK_ULONG siglen, CK_BYTE_PTR * data, CK_ULONG_PTR datalen) 605 { 606 CK_RV rv = c->sym->C_VerifyRecover(session, sig, siglen, NULL, datalen); 607 if (rv != CKR_OK) { 608 return rv; 609 } 610 *data = calloc(*datalen, sizeof(CK_BYTE)); 611 if (*data == NULL) { 612 return CKR_HOST_MEMORY; 613 } 614 rv = c->sym->C_VerifyRecover(session, sig, siglen, *data, datalen); 615 return rv; 616 } 617 618 CK_RV DigestEncryptUpdate(struct ctx * c, CK_SESSION_HANDLE session, 619 CK_BYTE_PTR part, CK_ULONG partlen, CK_BYTE_PTR * enc, 620 CK_ULONG_PTR enclen) 621 { 622 CK_RV rv = 623 c->sym->C_DigestEncryptUpdate(session, part, partlen, NULL, enclen); 624 if (rv != CKR_OK) { 625 return rv; 626 } 627 *enc = calloc(*enclen, sizeof(CK_BYTE)); 628 if (*enc == NULL) { 629 return CKR_HOST_MEMORY; 630 } 631 rv = c->sym->C_DigestEncryptUpdate(session, part, partlen, *enc, 632 enclen); 633 return rv; 634 } 635 636 CK_RV DecryptDigestUpdate(struct ctx * c, CK_SESSION_HANDLE session, 637 CK_BYTE_PTR cipher, CK_ULONG cipherlen, 638 CK_BYTE_PTR * part, CK_ULONG_PTR partlen) 639 { 640 CK_RV rv = 641 c->sym->C_DecryptDigestUpdate(session, cipher, cipherlen, NULL, 642 partlen); 643 if (rv != CKR_OK) { 644 return rv; 645 } 646 *part = calloc(*partlen, sizeof(CK_BYTE)); 647 if (*part == NULL) { 648 return CKR_HOST_MEMORY; 649 } 650 rv = c->sym->C_DecryptDigestUpdate(session, cipher, cipherlen, *part, 651 partlen); 652 return rv; 653 } 654 655 CK_RV SignEncryptUpdate(struct ctx * c, CK_SESSION_HANDLE session, 656 CK_BYTE_PTR part, CK_ULONG partlen, CK_BYTE_PTR * enc, 657 CK_ULONG_PTR enclen) 658 { 659 CK_RV rv = 660 c->sym->C_SignEncryptUpdate(session, part, partlen, NULL, enclen); 661 if (rv != CKR_OK) { 662 return rv; 663 } 664 *enc = calloc(*enclen, sizeof(CK_BYTE)); 665 if (*enc == NULL) { 666 return CKR_HOST_MEMORY; 667 } 668 rv = c->sym->C_SignEncryptUpdate(session, part, partlen, *enc, enclen); 669 return rv; 670 } 671 672 CK_RV DecryptVerifyUpdate(struct ctx * c, CK_SESSION_HANDLE session, 673 CK_BYTE_PTR cipher, CK_ULONG cipherlen, 674 CK_BYTE_PTR * part, CK_ULONG_PTR partlen) 675 { 676 CK_RV rv = 677 c->sym->C_DecryptVerifyUpdate(session, cipher, cipherlen, NULL, 678 partlen); 679 if (rv != CKR_OK) { 680 return rv; 681 } 682 *part = calloc(*partlen, sizeof(CK_BYTE)); 683 if (*part == NULL) { 684 return CKR_HOST_MEMORY; 685 } 686 rv = c->sym->C_DecryptVerifyUpdate(session, cipher, cipherlen, *part, 687 partlen); 688 return rv; 689 } 690 691 CK_RV GenerateKey(struct ctx * c, CK_SESSION_HANDLE session, 692 CK_MECHANISM_PTR mechanism, CK_ATTRIBUTE_PTR temp, 693 CK_ULONG tempCount, CK_OBJECT_HANDLE_PTR key) 694 { 695 return c->sym->C_GenerateKey(session, mechanism, temp, tempCount, key); 696 } 697 698 CK_RV GenerateKeyPair(struct ctx * c, CK_SESSION_HANDLE session, 699 CK_MECHANISM_PTR mechanism, CK_ATTRIBUTE_PTR pub, 700 CK_ULONG pubCount, CK_ATTRIBUTE_PTR priv, 701 CK_ULONG privCount, CK_OBJECT_HANDLE_PTR pubkey, 702 CK_OBJECT_HANDLE_PTR privkey) 703 { 704 return c->sym->C_GenerateKeyPair(session, mechanism, pub, pubCount, 705 priv, privCount, pubkey, privkey); 706 } 707 708 CK_RV WrapKey(struct ctx * c, CK_SESSION_HANDLE session, 709 CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE wrappingkey, 710 CK_OBJECT_HANDLE key, CK_BYTE_PTR * wrapped, 711 CK_ULONG_PTR wrappedlen) 712 { 713 CK_RV rv = c->sym->C_WrapKey(session, mechanism, wrappingkey, key, NULL, 714 wrappedlen); 715 if (rv != CKR_OK) { 716 return rv; 717 } 718 *wrapped = calloc(*wrappedlen, sizeof(CK_BYTE)); 719 if (*wrapped == NULL) { 720 return CKR_HOST_MEMORY; 721 } 722 rv = c->sym->C_WrapKey(session, mechanism, wrappingkey, key, *wrapped, 723 wrappedlen); 724 return rv; 725 } 726 727 CK_RV DeriveKey(struct ctx * c, CK_SESSION_HANDLE session, 728 CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE basekey, 729 CK_ATTRIBUTE_PTR a, CK_ULONG alen, CK_OBJECT_HANDLE_PTR key) 730 { 731 return c->sym->C_DeriveKey(session, mechanism, basekey, a, alen, key); 732 } 733 734 CK_RV UnwrapKey(struct ctx * c, CK_SESSION_HANDLE session, 735 CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE unwrappingkey, 736 CK_BYTE_PTR wrappedkey, CK_ULONG wrappedkeylen, 737 CK_ATTRIBUTE_PTR a, CK_ULONG alen, CK_OBJECT_HANDLE_PTR key) 738 { 739 return c->sym->C_UnwrapKey(session, mechanism, unwrappingkey, wrappedkey, 740 wrappedkeylen, a, alen, key); 741 } 742 743 CK_RV SeedRandom(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR seed, 744 CK_ULONG seedlen) 745 { 746 CK_RV e = c->sym->C_SeedRandom(session, seed, seedlen); 747 return e; 748 } 749 750 CK_RV GenerateRandom(struct ctx * c, CK_SESSION_HANDLE session, 751 CK_BYTE_PTR * rand, CK_ULONG length) 752 { 753 *rand = calloc(length, sizeof(CK_BYTE)); 754 if (*rand == NULL) { 755 return CKR_HOST_MEMORY; 756 } 757 CK_RV e = c->sym->C_GenerateRandom(session, *rand, length); 758 return e; 759 } 760 761 CK_RV WaitForSlotEvent(struct ctx * c, CK_FLAGS flags, CK_ULONG_PTR slot) 762 { 763 CK_RV e = 764 c->sym->C_WaitForSlotEvent(flags, (CK_SLOT_ID_PTR) slot, NULL); 765 return e; 766 } 767 768 static inline CK_VOID_PTR getAttributePval(CK_ATTRIBUTE_PTR a) 769 { 770 return a->pValue; 771 } 772 773 */ 774 import "C" 775 import ( 776 "strings" 777 "unsafe" 778 ) 779 780 // Ctx contains the current pkcs11 context. 781 type Ctx struct { 782 ctx *C.struct_ctx 783 } 784 785 // New creates a new context and initializes the module/library for use. 786 func New(module string) *Ctx { 787 c := new(Ctx) 788 mod := C.CString(module) 789 defer C.free(unsafe.Pointer(mod)) 790 c.ctx = C.New(mod) 791 if c.ctx == nil { 792 return nil 793 } 794 return c 795 } 796 797 // Destroy unloads the module/library and frees any remaining memory. 798 func (c *Ctx) Destroy() { 799 if c == nil || c.ctx == nil { 800 return 801 } 802 C.Destroy(c.ctx) 803 c.ctx = nil 804 } 805 806 // Initialize initializes the Cryptoki library. 807 func (c *Ctx) Initialize() error { 808 e := C.Initialize(c.ctx) 809 return toError(e) 810 } 811 812 // Finalize indicates that an application is done with the Cryptoki library. 813 func (c *Ctx) Finalize() error { 814 if c.ctx == nil { 815 return toError(CKR_CRYPTOKI_NOT_INITIALIZED) 816 } 817 e := C.Finalize(c.ctx) 818 return toError(e) 819 } 820 821 // GetInfo returns general information about Cryptoki. 822 func (c *Ctx) GetInfo() (Info, error) { 823 var p C.ckInfo 824 e := C.GetInfo(c.ctx, &p) 825 i := Info{ 826 CryptokiVersion: toVersion(p.cryptokiVersion), 827 ManufacturerID: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&p.manufacturerID[0]), 32)), " "), 828 Flags: uint(p.flags), 829 LibraryDescription: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&p.libraryDescription[0]), 32)), " "), 830 LibraryVersion: toVersion(p.libraryVersion), 831 } 832 return i, toError(e) 833 } 834 835 // GetSlotList obtains a list of slots in the system. 836 func (c *Ctx) GetSlotList(tokenPresent bool) ([]uint, error) { 837 var ( 838 slotList C.CK_ULONG_PTR 839 ulCount C.CK_ULONG 840 ) 841 e := C.GetSlotList(c.ctx, cBBool(tokenPresent), &slotList, &ulCount) 842 if toError(e) != nil { 843 return nil, toError(e) 844 } 845 l := toList(slotList, ulCount) 846 return l, nil 847 } 848 849 // GetSlotInfo obtains information about a particular slot in the system. 850 func (c *Ctx) GetSlotInfo(slotID uint) (SlotInfo, error) { 851 var csi C.CK_SLOT_INFO 852 e := C.GetSlotInfo(c.ctx, C.CK_ULONG(slotID), &csi) 853 s := SlotInfo{ 854 SlotDescription: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&csi.slotDescription[0]), 64)), " "), 855 ManufacturerID: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&csi.manufacturerID[0]), 32)), " "), 856 Flags: uint(csi.flags), 857 HardwareVersion: toVersion(csi.hardwareVersion), 858 FirmwareVersion: toVersion(csi.firmwareVersion), 859 } 860 return s, toError(e) 861 } 862 863 // GetTokenInfo obtains information about a particular token 864 // in the system. 865 func (c *Ctx) GetTokenInfo(slotID uint) (TokenInfo, error) { 866 var cti C.CK_TOKEN_INFO 867 e := C.GetTokenInfo(c.ctx, C.CK_ULONG(slotID), &cti) 868 s := TokenInfo{ 869 Label: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.label[0]), 32)), " "), 870 ManufacturerID: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.manufacturerID[0]), 32)), " "), 871 Model: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.model[0]), 16)), " "), 872 SerialNumber: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.serialNumber[0]), 16)), " "), 873 Flags: uint(cti.flags), 874 MaxSessionCount: uint(cti.ulMaxSessionCount), 875 SessionCount: uint(cti.ulSessionCount), 876 MaxRwSessionCount: uint(cti.ulMaxRwSessionCount), 877 RwSessionCount: uint(cti.ulRwSessionCount), 878 MaxPinLen: uint(cti.ulMaxPinLen), 879 MinPinLen: uint(cti.ulMinPinLen), 880 TotalPublicMemory: uint(cti.ulTotalPublicMemory), 881 FreePublicMemory: uint(cti.ulFreePublicMemory), 882 TotalPrivateMemory: uint(cti.ulTotalPrivateMemory), 883 FreePrivateMemory: uint(cti.ulFreePrivateMemory), 884 HardwareVersion: toVersion(cti.hardwareVersion), 885 FirmwareVersion: toVersion(cti.firmwareVersion), 886 UTCTime: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.utcTime[0]), 16)), " "), 887 } 888 return s, toError(e) 889 } 890 891 // GetMechanismList obtains a list of mechanism types supported by a token. 892 func (c *Ctx) GetMechanismList(slotID uint) ([]*Mechanism, error) { 893 var ( 894 mech C.CK_ULONG_PTR // in pkcs#11 we're all CK_ULONGs \o/ 895 mechlen C.CK_ULONG 896 ) 897 e := C.GetMechanismList(c.ctx, C.CK_ULONG(slotID), &mech, &mechlen) 898 if toError(e) != nil { 899 return nil, toError(e) 900 } 901 // Although the function returns only type, cast them back into real 902 // attributes as this is used in other functions. 903 m := make([]*Mechanism, int(mechlen)) 904 for i, typ := range toList(mech, mechlen) { 905 m[i] = NewMechanism(typ, nil) 906 } 907 return m, nil 908 } 909 910 // GetMechanismInfo obtains information about a particular 911 // mechanism possibly supported by a token. 912 func (c *Ctx) GetMechanismInfo(slotID uint, m []*Mechanism) (MechanismInfo, error) { 913 var cm C.CK_MECHANISM_INFO 914 e := C.GetMechanismInfo(c.ctx, C.CK_ULONG(slotID), C.CK_MECHANISM_TYPE(m[0].Mechanism), 915 C.CK_MECHANISM_INFO_PTR(&cm)) 916 mi := MechanismInfo{ 917 MinKeySize: uint(cm.ulMinKeySize), 918 MaxKeySize: uint(cm.ulMaxKeySize), 919 Flags: uint(cm.flags), 920 } 921 return mi, toError(e) 922 } 923 924 // InitToken initializes a token. The label must be 32 characters 925 // long, it is blank padded if it is not. If it is longer it is capped 926 // to 32 characters. 927 func (c *Ctx) InitToken(slotID uint, pin string, label string) error { 928 p := C.CString(pin) 929 defer C.free(unsafe.Pointer(p)) 930 ll := len(label) 931 for ll < 32 { 932 label += " " 933 ll++ 934 } 935 l := C.CString(label[:32]) 936 defer C.free(unsafe.Pointer(l)) 937 e := C.InitToken(c.ctx, C.CK_ULONG(slotID), p, C.CK_ULONG(len(pin)), l) 938 return toError(e) 939 } 940 941 // InitPIN initializes the normal user's PIN. 942 func (c *Ctx) InitPIN(sh SessionHandle, pin string) error { 943 p := C.CString(pin) 944 defer C.free(unsafe.Pointer(p)) 945 e := C.InitPIN(c.ctx, C.CK_SESSION_HANDLE(sh), p, C.CK_ULONG(len(pin))) 946 return toError(e) 947 } 948 949 // SetPIN modifies the PIN of the user who is logged in. 950 func (c *Ctx) SetPIN(sh SessionHandle, oldpin string, newpin string) error { 951 old := C.CString(oldpin) 952 defer C.free(unsafe.Pointer(old)) 953 new := C.CString(newpin) 954 defer C.free(unsafe.Pointer(new)) 955 e := C.SetPIN(c.ctx, C.CK_SESSION_HANDLE(sh), old, C.CK_ULONG(len(oldpin)), new, C.CK_ULONG(len(newpin))) 956 return toError(e) 957 } 958 959 // OpenSession opens a session between an application and a token. 960 func (c *Ctx) OpenSession(slotID uint, flags uint) (SessionHandle, error) { 961 var s C.CK_SESSION_HANDLE 962 e := C.OpenSession(c.ctx, C.CK_ULONG(slotID), C.CK_ULONG(flags), C.CK_SESSION_HANDLE_PTR(&s)) 963 return SessionHandle(s), toError(e) 964 } 965 966 // CloseSession closes a session between an application and a token. 967 func (c *Ctx) CloseSession(sh SessionHandle) error { 968 if c.ctx == nil { 969 return toError(CKR_CRYPTOKI_NOT_INITIALIZED) 970 } 971 e := C.CloseSession(c.ctx, C.CK_SESSION_HANDLE(sh)) 972 return toError(e) 973 } 974 975 // CloseAllSessions closes all sessions with a token. 976 func (c *Ctx) CloseAllSessions(slotID uint) error { 977 if c.ctx == nil { 978 return toError(CKR_CRYPTOKI_NOT_INITIALIZED) 979 } 980 e := C.CloseAllSessions(c.ctx, C.CK_ULONG(slotID)) 981 return toError(e) 982 } 983 984 // GetSessionInfo obtains information about the session. 985 func (c *Ctx) GetSessionInfo(sh SessionHandle) (SessionInfo, error) { 986 var csi C.CK_SESSION_INFO 987 e := C.GetSessionInfo(c.ctx, C.CK_SESSION_HANDLE(sh), &csi) 988 s := SessionInfo{SlotID: uint(csi.slotID), 989 State: uint(csi.state), 990 Flags: uint(csi.flags), 991 DeviceError: uint(csi.ulDeviceError), 992 } 993 return s, toError(e) 994 } 995 996 // GetOperationState obtains the state of the cryptographic operation in a session. 997 func (c *Ctx) GetOperationState(sh SessionHandle) ([]byte, error) { 998 var ( 999 state C.CK_BYTE_PTR 1000 statelen C.CK_ULONG 1001 ) 1002 e := C.GetOperationState(c.ctx, C.CK_SESSION_HANDLE(sh), &state, &statelen) 1003 defer C.free(unsafe.Pointer(state)) 1004 if toError(e) != nil { 1005 return nil, toError(e) 1006 } 1007 b := C.GoBytes(unsafe.Pointer(state), C.int(statelen)) 1008 return b, nil 1009 } 1010 1011 // SetOperationState restores the state of the cryptographic operation in a session. 1012 func (c *Ctx) SetOperationState(sh SessionHandle, state []byte, encryptKey, authKey ObjectHandle) error { 1013 e := C.SetOperationState(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&state[0])), 1014 C.CK_ULONG(len(state)), C.CK_OBJECT_HANDLE(encryptKey), C.CK_OBJECT_HANDLE(authKey)) 1015 return toError(e) 1016 } 1017 1018 // Login logs a user into a token. 1019 func (c *Ctx) Login(sh SessionHandle, userType uint, pin string) error { 1020 p := C.CString(pin) 1021 defer C.free(unsafe.Pointer(p)) 1022 e := C.Login(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_USER_TYPE(userType), p, C.CK_ULONG(len(pin))) 1023 return toError(e) 1024 } 1025 1026 // Logout logs a user out from a token. 1027 func (c *Ctx) Logout(sh SessionHandle) error { 1028 if c.ctx == nil { 1029 return toError(CKR_CRYPTOKI_NOT_INITIALIZED) 1030 } 1031 e := C.Logout(c.ctx, C.CK_SESSION_HANDLE(sh)) 1032 return toError(e) 1033 } 1034 1035 // CreateObject creates a new object. 1036 func (c *Ctx) CreateObject(sh SessionHandle, temp []*Attribute) (ObjectHandle, error) { 1037 var obj C.CK_OBJECT_HANDLE 1038 arena, t, tcount := cAttributeList(temp) 1039 defer arena.Free() 1040 e := C.CreateObject(c.ctx, C.CK_SESSION_HANDLE(sh), t, tcount, C.CK_OBJECT_HANDLE_PTR(&obj)) 1041 e1 := toError(e) 1042 if e1 == nil { 1043 return ObjectHandle(obj), nil 1044 } 1045 return 0, e1 1046 } 1047 1048 // CopyObject copies an object, creating a new object for the copy. 1049 func (c *Ctx) CopyObject(sh SessionHandle, o ObjectHandle, temp []*Attribute) (ObjectHandle, error) { 1050 var obj C.CK_OBJECT_HANDLE 1051 arena, t, tcount := cAttributeList(temp) 1052 defer arena.Free() 1053 1054 e := C.CopyObject(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(o), t, tcount, C.CK_OBJECT_HANDLE_PTR(&obj)) 1055 e1 := toError(e) 1056 if e1 == nil { 1057 return ObjectHandle(obj), nil 1058 } 1059 return 0, e1 1060 } 1061 1062 // DestroyObject destroys an object. 1063 func (c *Ctx) DestroyObject(sh SessionHandle, oh ObjectHandle) error { 1064 e := C.DestroyObject(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(oh)) 1065 return toError(e) 1066 } 1067 1068 // GetObjectSize gets the size of an object in bytes. 1069 func (c *Ctx) GetObjectSize(sh SessionHandle, oh ObjectHandle) (uint, error) { 1070 var size C.CK_ULONG 1071 e := C.GetObjectSize(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(oh), &size) 1072 return uint(size), toError(e) 1073 } 1074 1075 // GetAttributeValue obtains the value of one or more object attributes. 1076 func (c *Ctx) GetAttributeValue(sh SessionHandle, o ObjectHandle, a []*Attribute) ([]*Attribute, error) { 1077 // copy the attribute list and make all the values nil, so that 1078 // the C function can (allocate) fill them in 1079 pa := make([]C.CK_ATTRIBUTE, len(a)) 1080 for i := 0; i < len(a); i++ { 1081 pa[i]._type = C.CK_ATTRIBUTE_TYPE(a[i].Type) 1082 } 1083 e := C.GetAttributeValue(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(o), &pa[0], C.CK_ULONG(len(a))) 1084 if err := toError(e); err != nil { 1085 return nil, err 1086 } 1087 a1 := make([]*Attribute, len(a)) 1088 for i, c := range pa { 1089 x := new(Attribute) 1090 x.Type = uint(c._type) 1091 if int(c.ulValueLen) != -1 { 1092 buf := unsafe.Pointer(C.getAttributePval(&c)) 1093 x.Value = C.GoBytes(buf, C.int(c.ulValueLen)) 1094 C.free(buf) 1095 } 1096 a1[i] = x 1097 } 1098 return a1, nil 1099 } 1100 1101 // SetAttributeValue modifies the value of one or more object attributes 1102 func (c *Ctx) SetAttributeValue(sh SessionHandle, o ObjectHandle, a []*Attribute) error { 1103 arena, pa, palen := cAttributeList(a) 1104 defer arena.Free() 1105 e := C.SetAttributeValue(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(o), pa, palen) 1106 return toError(e) 1107 } 1108 1109 // FindObjectsInit initializes a search for token and session 1110 // objects that match a template. 1111 func (c *Ctx) FindObjectsInit(sh SessionHandle, temp []*Attribute) error { 1112 arena, t, tcount := cAttributeList(temp) 1113 defer arena.Free() 1114 e := C.FindObjectsInit(c.ctx, C.CK_SESSION_HANDLE(sh), t, tcount) 1115 return toError(e) 1116 } 1117 1118 // FindObjects continues a search for token and session 1119 // objects that match a template, obtaining additional object 1120 // handles. Calling the function repeatedly may yield additional results until 1121 // an empty slice is returned. 1122 // 1123 // The returned boolean value is deprecated and should be ignored. 1124 func (c *Ctx) FindObjects(sh SessionHandle, max int) ([]ObjectHandle, bool, error) { 1125 var ( 1126 objectList C.CK_OBJECT_HANDLE_PTR 1127 ulCount C.CK_ULONG 1128 ) 1129 e := C.FindObjects(c.ctx, C.CK_SESSION_HANDLE(sh), &objectList, C.CK_ULONG(max), &ulCount) 1130 if toError(e) != nil { 1131 return nil, false, toError(e) 1132 } 1133 l := toList(C.CK_ULONG_PTR(unsafe.Pointer(objectList)), ulCount) 1134 // Make again a new list of the correct type. 1135 // This is copying data, but this is not an often used function. 1136 o := make([]ObjectHandle, len(l)) 1137 for i, v := range l { 1138 o[i] = ObjectHandle(v) 1139 } 1140 return o, ulCount > C.CK_ULONG(max), nil 1141 } 1142 1143 // FindObjectsFinal finishes a search for token and session objects. 1144 func (c *Ctx) FindObjectsFinal(sh SessionHandle) error { 1145 e := C.FindObjectsFinal(c.ctx, C.CK_SESSION_HANDLE(sh)) 1146 return toError(e) 1147 } 1148 1149 // EncryptInit initializes an encryption operation. 1150 func (c *Ctx) EncryptInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error { 1151 arena, mech := cMechanism(m) 1152 defer arena.Free() 1153 e := C.EncryptInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o)) 1154 return toError(e) 1155 } 1156 1157 // Encrypt encrypts single-part data. 1158 func (c *Ctx) Encrypt(sh SessionHandle, message []byte) ([]byte, error) { 1159 var ( 1160 enc C.CK_BYTE_PTR 1161 enclen C.CK_ULONG 1162 ) 1163 e := C.Encrypt(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(message), C.CK_ULONG(len(message)), &enc, &enclen) 1164 if toError(e) != nil { 1165 return nil, toError(e) 1166 } 1167 s := C.GoBytes(unsafe.Pointer(enc), C.int(enclen)) 1168 C.free(unsafe.Pointer(enc)) 1169 return s, nil 1170 } 1171 1172 // EncryptUpdate continues a multiple-part encryption operation. 1173 func (c *Ctx) EncryptUpdate(sh SessionHandle, plain []byte) ([]byte, error) { 1174 var ( 1175 part C.CK_BYTE_PTR 1176 partlen C.CK_ULONG 1177 ) 1178 e := C.EncryptUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(plain), C.CK_ULONG(len(plain)), &part, &partlen) 1179 if toError(e) != nil { 1180 return nil, toError(e) 1181 } 1182 h := C.GoBytes(unsafe.Pointer(part), C.int(partlen)) 1183 C.free(unsafe.Pointer(part)) 1184 return h, nil 1185 } 1186 1187 // EncryptFinal finishes a multiple-part encryption operation. 1188 func (c *Ctx) EncryptFinal(sh SessionHandle) ([]byte, error) { 1189 var ( 1190 enc C.CK_BYTE_PTR 1191 enclen C.CK_ULONG 1192 ) 1193 e := C.EncryptFinal(c.ctx, C.CK_SESSION_HANDLE(sh), &enc, &enclen) 1194 if toError(e) != nil { 1195 return nil, toError(e) 1196 } 1197 h := C.GoBytes(unsafe.Pointer(enc), C.int(enclen)) 1198 C.free(unsafe.Pointer(enc)) 1199 return h, nil 1200 } 1201 1202 // DecryptInit initializes a decryption operation. 1203 func (c *Ctx) DecryptInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error { 1204 arena, mech := cMechanism(m) 1205 defer arena.Free() 1206 e := C.DecryptInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o)) 1207 return toError(e) 1208 } 1209 1210 // Decrypt decrypts encrypted data in a single part. 1211 func (c *Ctx) Decrypt(sh SessionHandle, cipher []byte) ([]byte, error) { 1212 var ( 1213 plain C.CK_BYTE_PTR 1214 plainlen C.CK_ULONG 1215 ) 1216 e := C.Decrypt(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(cipher), C.CK_ULONG(len(cipher)), &plain, &plainlen) 1217 if toError(e) != nil { 1218 return nil, toError(e) 1219 } 1220 s := C.GoBytes(unsafe.Pointer(plain), C.int(plainlen)) 1221 C.free(unsafe.Pointer(plain)) 1222 return s, nil 1223 } 1224 1225 // DecryptUpdate continues a multiple-part decryption operation. 1226 func (c *Ctx) DecryptUpdate(sh SessionHandle, cipher []byte) ([]byte, error) { 1227 var ( 1228 part C.CK_BYTE_PTR 1229 partlen C.CK_ULONG 1230 ) 1231 e := C.DecryptUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(cipher), C.CK_ULONG(len(cipher)), &part, &partlen) 1232 if toError(e) != nil { 1233 return nil, toError(e) 1234 } 1235 h := C.GoBytes(unsafe.Pointer(part), C.int(partlen)) 1236 C.free(unsafe.Pointer(part)) 1237 return h, nil 1238 } 1239 1240 // DecryptFinal finishes a multiple-part decryption operation. 1241 func (c *Ctx) DecryptFinal(sh SessionHandle) ([]byte, error) { 1242 var ( 1243 plain C.CK_BYTE_PTR 1244 plainlen C.CK_ULONG 1245 ) 1246 e := C.DecryptFinal(c.ctx, C.CK_SESSION_HANDLE(sh), &plain, &plainlen) 1247 if toError(e) != nil { 1248 return nil, toError(e) 1249 } 1250 h := C.GoBytes(unsafe.Pointer(plain), C.int(plainlen)) 1251 C.free(unsafe.Pointer(plain)) 1252 return h, nil 1253 } 1254 1255 // DigestInit initializes a message-digesting operation. 1256 func (c *Ctx) DigestInit(sh SessionHandle, m []*Mechanism) error { 1257 arena, mech := cMechanism(m) 1258 defer arena.Free() 1259 e := C.DigestInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech) 1260 return toError(e) 1261 } 1262 1263 // Digest digests message in a single part. 1264 func (c *Ctx) Digest(sh SessionHandle, message []byte) ([]byte, error) { 1265 var ( 1266 hash C.CK_BYTE_PTR 1267 hashlen C.CK_ULONG 1268 ) 1269 e := C.Digest(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(message), C.CK_ULONG(len(message)), &hash, &hashlen) 1270 if toError(e) != nil { 1271 return nil, toError(e) 1272 } 1273 h := C.GoBytes(unsafe.Pointer(hash), C.int(hashlen)) 1274 C.free(unsafe.Pointer(hash)) 1275 return h, nil 1276 } 1277 1278 // DigestUpdate continues a multiple-part message-digesting operation. 1279 func (c *Ctx) DigestUpdate(sh SessionHandle, message []byte) error { 1280 e := C.DigestUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(message), C.CK_ULONG(len(message))) 1281 if toError(e) != nil { 1282 return toError(e) 1283 } 1284 return nil 1285 } 1286 1287 // DigestKey continues a multi-part message-digesting 1288 // operation, by digesting the value of a secret key as part of 1289 // the data already digested. 1290 func (c *Ctx) DigestKey(sh SessionHandle, key ObjectHandle) error { 1291 e := C.DigestKey(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(key)) 1292 if toError(e) != nil { 1293 return toError(e) 1294 } 1295 return nil 1296 } 1297 1298 // DigestFinal finishes a multiple-part message-digesting operation. 1299 func (c *Ctx) DigestFinal(sh SessionHandle) ([]byte, error) { 1300 var ( 1301 hash C.CK_BYTE_PTR 1302 hashlen C.CK_ULONG 1303 ) 1304 e := C.DigestFinal(c.ctx, C.CK_SESSION_HANDLE(sh), &hash, &hashlen) 1305 if toError(e) != nil { 1306 return nil, toError(e) 1307 } 1308 h := C.GoBytes(unsafe.Pointer(hash), C.int(hashlen)) 1309 C.free(unsafe.Pointer(hash)) 1310 return h, nil 1311 } 1312 1313 // SignInit initializes a signature (private key encryption) 1314 // operation, where the signature is (will be) an appendix to 1315 // the data, and plaintext cannot be recovered from the signature. 1316 func (c *Ctx) SignInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error { 1317 arena, mech := cMechanism(m) 1318 defer arena.Free() 1319 e := C.SignInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o)) 1320 return toError(e) 1321 } 1322 1323 // Sign signs (encrypts with private key) data in a single part, where the signature 1324 // is (will be) an appendix to the data, and plaintext cannot be recovered from the signature. 1325 func (c *Ctx) Sign(sh SessionHandle, message []byte) ([]byte, error) { 1326 var ( 1327 sig C.CK_BYTE_PTR 1328 siglen C.CK_ULONG 1329 ) 1330 e := C.Sign(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(message), C.CK_ULONG(len(message)), &sig, &siglen) 1331 if toError(e) != nil { 1332 return nil, toError(e) 1333 } 1334 s := C.GoBytes(unsafe.Pointer(sig), C.int(siglen)) 1335 C.free(unsafe.Pointer(sig)) 1336 return s, nil 1337 } 1338 1339 // SignUpdate continues a multiple-part signature operation, 1340 // where the signature is (will be) an appendix to the data, 1341 // and plaintext cannot be recovered from the signature. 1342 func (c *Ctx) SignUpdate(sh SessionHandle, message []byte) error { 1343 e := C.SignUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(message), C.CK_ULONG(len(message))) 1344 return toError(e) 1345 } 1346 1347 // SignFinal finishes a multiple-part signature operation returning the signature. 1348 func (c *Ctx) SignFinal(sh SessionHandle) ([]byte, error) { 1349 var ( 1350 sig C.CK_BYTE_PTR 1351 siglen C.CK_ULONG 1352 ) 1353 e := C.SignFinal(c.ctx, C.CK_SESSION_HANDLE(sh), &sig, &siglen) 1354 if toError(e) != nil { 1355 return nil, toError(e) 1356 } 1357 h := C.GoBytes(unsafe.Pointer(sig), C.int(siglen)) 1358 C.free(unsafe.Pointer(sig)) 1359 return h, nil 1360 } 1361 1362 // SignRecoverInit initializes a signature operation, where the data can be recovered from the signature. 1363 func (c *Ctx) SignRecoverInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error { 1364 arena, mech := cMechanism(m) 1365 defer arena.Free() 1366 e := C.SignRecoverInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(key)) 1367 return toError(e) 1368 } 1369 1370 // SignRecover signs data in a single operation, where the data can be recovered from the signature. 1371 func (c *Ctx) SignRecover(sh SessionHandle, data []byte) ([]byte, error) { 1372 var ( 1373 sig C.CK_BYTE_PTR 1374 siglen C.CK_ULONG 1375 ) 1376 e := C.SignRecover(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(data), C.CK_ULONG(len(data)), &sig, &siglen) 1377 if toError(e) != nil { 1378 return nil, toError(e) 1379 } 1380 h := C.GoBytes(unsafe.Pointer(sig), C.int(siglen)) 1381 C.free(unsafe.Pointer(sig)) 1382 return h, nil 1383 } 1384 1385 // VerifyInit initializes a verification operation, where the 1386 // signature is an appendix to the data, and plaintext cannot 1387 // be recovered from the signature (e.g. DSA). 1388 func (c *Ctx) VerifyInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error { 1389 arena, mech := cMechanism(m) 1390 defer arena.Free() 1391 e := C.VerifyInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(key)) 1392 return toError(e) 1393 } 1394 1395 // Verify verifies a signature in a single-part operation, 1396 // where the signature is an appendix to the data, and plaintext 1397 // cannot be recovered from the signature. 1398 func (c *Ctx) Verify(sh SessionHandle, data []byte, signature []byte) error { 1399 e := C.Verify(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(data), C.CK_ULONG(len(data)), cMessage(signature), C.CK_ULONG(len(signature))) 1400 return toError(e) 1401 } 1402 1403 // VerifyUpdate continues a multiple-part verification 1404 // operation, where the signature is an appendix to the data, 1405 // and plaintext cannot be recovered from the signature. 1406 func (c *Ctx) VerifyUpdate(sh SessionHandle, part []byte) error { 1407 e := C.VerifyUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(part), C.CK_ULONG(len(part))) 1408 return toError(e) 1409 } 1410 1411 // VerifyFinal finishes a multiple-part verification 1412 // operation, checking the signature. 1413 func (c *Ctx) VerifyFinal(sh SessionHandle, signature []byte) error { 1414 e := C.VerifyFinal(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(signature), C.CK_ULONG(len(signature))) 1415 return toError(e) 1416 } 1417 1418 // VerifyRecoverInit initializes a signature verification 1419 // operation, where the data is recovered from the signature. 1420 func (c *Ctx) VerifyRecoverInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error { 1421 arena, mech := cMechanism(m) 1422 defer arena.Free() 1423 e := C.VerifyRecoverInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(key)) 1424 return toError(e) 1425 } 1426 1427 // VerifyRecover verifies a signature in a single-part 1428 // operation, where the data is recovered from the signature. 1429 func (c *Ctx) VerifyRecover(sh SessionHandle, signature []byte) ([]byte, error) { 1430 var ( 1431 data C.CK_BYTE_PTR 1432 datalen C.CK_ULONG 1433 ) 1434 e := C.DecryptVerifyUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(signature), C.CK_ULONG(len(signature)), &data, &datalen) 1435 if toError(e) != nil { 1436 return nil, toError(e) 1437 } 1438 h := C.GoBytes(unsafe.Pointer(data), C.int(datalen)) 1439 C.free(unsafe.Pointer(data)) 1440 return h, nil 1441 } 1442 1443 // DigestEncryptUpdate continues a multiple-part digesting and encryption operation. 1444 func (c *Ctx) DigestEncryptUpdate(sh SessionHandle, part []byte) ([]byte, error) { 1445 var ( 1446 enc C.CK_BYTE_PTR 1447 enclen C.CK_ULONG 1448 ) 1449 e := C.DigestEncryptUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(part), C.CK_ULONG(len(part)), &enc, &enclen) 1450 if toError(e) != nil { 1451 return nil, toError(e) 1452 } 1453 h := C.GoBytes(unsafe.Pointer(enc), C.int(enclen)) 1454 C.free(unsafe.Pointer(enc)) 1455 return h, nil 1456 } 1457 1458 // DecryptDigestUpdate continues a multiple-part decryption and digesting operation. 1459 func (c *Ctx) DecryptDigestUpdate(sh SessionHandle, cipher []byte) ([]byte, error) { 1460 var ( 1461 part C.CK_BYTE_PTR 1462 partlen C.CK_ULONG 1463 ) 1464 e := C.DecryptDigestUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(cipher), C.CK_ULONG(len(cipher)), &part, &partlen) 1465 if toError(e) != nil { 1466 return nil, toError(e) 1467 } 1468 h := C.GoBytes(unsafe.Pointer(part), C.int(partlen)) 1469 C.free(unsafe.Pointer(part)) 1470 return h, nil 1471 } 1472 1473 // SignEncryptUpdate continues a multiple-part signing and encryption operation. 1474 func (c *Ctx) SignEncryptUpdate(sh SessionHandle, part []byte) ([]byte, error) { 1475 var ( 1476 enc C.CK_BYTE_PTR 1477 enclen C.CK_ULONG 1478 ) 1479 e := C.SignEncryptUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(part), C.CK_ULONG(len(part)), &enc, &enclen) 1480 if toError(e) != nil { 1481 return nil, toError(e) 1482 } 1483 h := C.GoBytes(unsafe.Pointer(enc), C.int(enclen)) 1484 C.free(unsafe.Pointer(enc)) 1485 return h, nil 1486 } 1487 1488 // DecryptVerifyUpdate continues a multiple-part decryption and verify operation. 1489 func (c *Ctx) DecryptVerifyUpdate(sh SessionHandle, cipher []byte) ([]byte, error) { 1490 var ( 1491 part C.CK_BYTE_PTR 1492 partlen C.CK_ULONG 1493 ) 1494 e := C.DecryptVerifyUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), cMessage(cipher), C.CK_ULONG(len(cipher)), &part, &partlen) 1495 if toError(e) != nil { 1496 return nil, toError(e) 1497 } 1498 h := C.GoBytes(unsafe.Pointer(part), C.int(partlen)) 1499 C.free(unsafe.Pointer(part)) 1500 return h, nil 1501 } 1502 1503 // GenerateKey generates a secret key, creating a new key object. 1504 func (c *Ctx) GenerateKey(sh SessionHandle, m []*Mechanism, temp []*Attribute) (ObjectHandle, error) { 1505 var key C.CK_OBJECT_HANDLE 1506 attrarena, t, tcount := cAttributeList(temp) 1507 defer attrarena.Free() 1508 mecharena, mech := cMechanism(m) 1509 defer mecharena.Free() 1510 e := C.GenerateKey(c.ctx, C.CK_SESSION_HANDLE(sh), mech, t, tcount, C.CK_OBJECT_HANDLE_PTR(&key)) 1511 e1 := toError(e) 1512 if e1 == nil { 1513 return ObjectHandle(key), nil 1514 } 1515 return 0, e1 1516 } 1517 1518 // GenerateKeyPair generates a public-key/private-key pair creating new key objects. 1519 func (c *Ctx) GenerateKeyPair(sh SessionHandle, m []*Mechanism, public, private []*Attribute) (ObjectHandle, ObjectHandle, error) { 1520 var ( 1521 pubkey C.CK_OBJECT_HANDLE 1522 privkey C.CK_OBJECT_HANDLE 1523 ) 1524 pubarena, pub, pubcount := cAttributeList(public) 1525 defer pubarena.Free() 1526 privarena, priv, privcount := cAttributeList(private) 1527 defer privarena.Free() 1528 mecharena, mech := cMechanism(m) 1529 defer mecharena.Free() 1530 e := C.GenerateKeyPair(c.ctx, C.CK_SESSION_HANDLE(sh), mech, pub, pubcount, priv, privcount, C.CK_OBJECT_HANDLE_PTR(&pubkey), C.CK_OBJECT_HANDLE_PTR(&privkey)) 1531 e1 := toError(e) 1532 if e1 == nil { 1533 return ObjectHandle(pubkey), ObjectHandle(privkey), nil 1534 } 1535 return 0, 0, e1 1536 } 1537 1538 // WrapKey wraps (i.e., encrypts) a key. 1539 func (c *Ctx) WrapKey(sh SessionHandle, m []*Mechanism, wrappingkey, key ObjectHandle) ([]byte, error) { 1540 var ( 1541 wrappedkey C.CK_BYTE_PTR 1542 wrappedkeylen C.CK_ULONG 1543 ) 1544 arena, mech := cMechanism(m) 1545 defer arena.Free() 1546 e := C.WrapKey(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(wrappingkey), C.CK_OBJECT_HANDLE(key), &wrappedkey, &wrappedkeylen) 1547 if toError(e) != nil { 1548 return nil, toError(e) 1549 } 1550 h := C.GoBytes(unsafe.Pointer(wrappedkey), C.int(wrappedkeylen)) 1551 C.free(unsafe.Pointer(wrappedkey)) 1552 return h, nil 1553 } 1554 1555 // UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. 1556 func (c *Ctx) UnwrapKey(sh SessionHandle, m []*Mechanism, unwrappingkey ObjectHandle, wrappedkey []byte, a []*Attribute) (ObjectHandle, error) { 1557 var key C.CK_OBJECT_HANDLE 1558 attrarena, ac, aclen := cAttributeList(a) 1559 defer attrarena.Free() 1560 mecharena, mech := cMechanism(m) 1561 defer mecharena.Free() 1562 e := C.UnwrapKey(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(unwrappingkey), C.CK_BYTE_PTR(unsafe.Pointer(&wrappedkey[0])), C.CK_ULONG(len(wrappedkey)), ac, aclen, &key) 1563 return ObjectHandle(key), toError(e) 1564 } 1565 1566 // DeriveKey derives a key from a base key, creating a new key object. 1567 func (c *Ctx) DeriveKey(sh SessionHandle, m []*Mechanism, basekey ObjectHandle, a []*Attribute) (ObjectHandle, error) { 1568 var key C.CK_OBJECT_HANDLE 1569 attrarena, ac, aclen := cAttributeList(a) 1570 defer attrarena.Free() 1571 mecharena, mech := cMechanism(m) 1572 defer mecharena.Free() 1573 e := C.DeriveKey(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(basekey), ac, aclen, &key) 1574 return ObjectHandle(key), toError(e) 1575 } 1576 1577 // SeedRandom mixes additional seed material into the token's 1578 // random number generator. 1579 func (c *Ctx) SeedRandom(sh SessionHandle, seed []byte) error { 1580 e := C.SeedRandom(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&seed[0])), C.CK_ULONG(len(seed))) 1581 return toError(e) 1582 } 1583 1584 // GenerateRandom generates random data. 1585 func (c *Ctx) GenerateRandom(sh SessionHandle, length int) ([]byte, error) { 1586 var rand C.CK_BYTE_PTR 1587 e := C.GenerateRandom(c.ctx, C.CK_SESSION_HANDLE(sh), &rand, C.CK_ULONG(length)) 1588 if toError(e) != nil { 1589 return nil, toError(e) 1590 } 1591 h := C.GoBytes(unsafe.Pointer(rand), C.int(length)) 1592 C.free(unsafe.Pointer(rand)) 1593 return h, nil 1594 } 1595 1596 // WaitForSlotEvent returns a channel which returns a slot event 1597 // (token insertion, removal, etc.) when it occurs. 1598 func (c *Ctx) WaitForSlotEvent(flags uint) chan SlotEvent { 1599 sl := make(chan SlotEvent, 1) // hold one element 1600 go c.waitForSlotEventHelper(flags, sl) 1601 return sl 1602 } 1603 1604 func (c *Ctx) waitForSlotEventHelper(f uint, sl chan SlotEvent) { 1605 var slotID C.CK_ULONG 1606 C.WaitForSlotEvent(c.ctx, C.CK_FLAGS(f), &slotID) 1607 sl <- SlotEvent{uint(slotID)} 1608 close(sl) // TODO(miek): Sending and then closing ...? 1609 } 1610