Example #1
0
nsresult
KeyService::Init()
{
    // Bring up psm
    nsCOMPtr<nsISupports> nss = do_GetService("@mozilla.org/psm;1");
    SECStatus sv;
    mSlot = PK11_GetInternalKeySlot();
    
    if (PK11_NeedUserInit(mSlot)) {
        NS_ConvertUTF8toUTF16 tokenName(PK11_GetTokenName(mSlot));
        
        nsCOMPtr<nsITokenPasswordDialogs> dialogs;
        dialogs = do_GetService(NS_TOKENPASSWORDSDIALOG_CONTRACTID);
        if (!dialogs)
            return NS_ERROR_FAILURE;
        
        PRBool cancelled;
        nsresult rv = dialogs->SetPassword(nsnull, tokenName.get(), &cancelled);
        NS_ENSURE_SUCCESS(rv, rv);
        
        if (cancelled)
            return NS_ERROR_FAILURE;
    }
    
    if (PK11_NeedLogin(mSlot)) {
        sv = PK11_Authenticate(mSlot, PR_TRUE, NULL);
        if (sv != SECSuccess)
            return NS_ERROR_FAILURE;
    }
    
    return NS_OK;
}
Example #2
0
File: nss.c Project: 0w/moai-dev
static int nss_load_key(struct connectdata *conn, int sockindex, char *key_file)
{
#ifdef HAVE_PK11_CREATEGENERICOBJECT
  PK11SlotInfo * slot = NULL;
  CK_ATTRIBUTE *attrs;
  CK_ATTRIBUTE theTemplate[20];
  CK_BBOOL cktrue = CK_TRUE;
  CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
  CK_SLOT_ID slotID;
  char slotname[SLOTSIZE];
  struct ssl_connect_data *sslconn = &conn->ssl[sockindex];

  attrs = theTemplate;

  /* FIXME: grok the various file types */

  slotID = 1; /* hardcoded for now */

  snprintf(slotname, sizeof(slotname), "PEM Token #%ld", slotID);
  slot = PK11_FindSlotByName(slotname);

  if(!slot)
    return 0;

  PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass) ); attrs++;
  PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL) ); attrs++;
  PK11_SETATTRS(attrs, CKA_LABEL, (unsigned char *)key_file,
                strlen(key_file)+1); attrs++;

  /* When adding an encrypted key the PKCS#11 will be set as removed */
  sslconn->key = PK11_CreateGenericObject(slot, theTemplate, 3,
                                          PR_FALSE /* isPerm */);
  if(sslconn->key == NULL) {
    PR_SetError(SEC_ERROR_BAD_KEY, 0);
    return 0;
  }

  /* This will force the token to be seen as re-inserted */
  SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
  PK11_IsPresent(slot);

  /* parg is initialized in nss_Init_Tokens() */
  if(PK11_Authenticate(slot, PR_TRUE,
                       conn->data->set.str[STRING_KEY_PASSWD]) != SECSuccess) {

    PK11_FreeSlot(slot);
    return 0;
  }
  PK11_FreeSlot(slot);

  return 1;
#else
  /* If we don't have PK11_CreateGenericObject then we can't load a file-based
   * key.
   */
  (void)conn; /* unused */
  (void)key_file; /* unused */
  return 0;
#endif
}
Example #3
0
File: nss.c Project: zcopley/curl
static int nss_load_key(struct connectdata *conn, int sockindex,
                        char *key_file)
{
#ifdef HAVE_PK11_CREATEGENERICOBJECT
  PK11SlotInfo *slot;
  SECStatus status;
  struct ssl_connect_data *ssl = conn->ssl;

  if(CURLE_OK != nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE)) {
    PR_SetError(SEC_ERROR_BAD_KEY, 0);
    return 0;
  }

  slot = PK11_FindSlotByName("PEM Token #1");
  if(!slot)
    return 0;

  /* This will force the token to be seen as re-inserted */
  SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
  PK11_IsPresent(slot);

  status = PK11_Authenticate(slot, PR_TRUE,
                             conn->data->set.str[STRING_KEY_PASSWD]);
  PK11_FreeSlot(slot);
  return (SECSuccess == status) ? 1 : 0;
#else
  /* If we don't have PK11_CreateGenericObject then we can't load a file-based
   * key.
   */
  (void)conn; /* unused */
  (void)key_file; /* unused */
  return 0;
#endif
}
Example #4
0
/******************************************************************
 *
 * G e n e r a t e K e y P a i r
 */
static SECStatus
GenerateKeyPair(PK11SlotInfo *slot, SECKEYPublicKey **pubk,
SECKEYPrivateKey **privk, int keysize)
{

    PK11RSAGenParams rsaParams;

    if ( keysize == -1 ) {
	rsaParams.keySizeInBits = DEFAULT_RSA_KEY_SIZE;
    } else {
	rsaParams.keySizeInBits = keysize;
    }
    rsaParams.pe = 0x10001;

    if (PK11_Authenticate( slot, PR_FALSE /*loadCerts*/, &pwdata)
         != SECSuccess) {
	SECU_PrintError(progName, "failure authenticating to key database.\n");
	exit(ERRX);
    }

    *privk = PK11_GenerateKeyPair (slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &rsaParams,
         
        pubk, PR_TRUE /*isPerm*/, PR_TRUE /*isSensitive*/, &pwdata);

    if (*privk != NULL && *pubk != NULL) {
	if (verbosity >= 0) {
	    PR_fprintf(outputFD, "generated public/private key pair\n");
	}
    } else {
	SECU_PrintError(progName, "failure generating key pair\n");
	exit (ERRX);
    }

    return SECSuccess;
}
Example #5
0
/**
 * xmlSecNssGetInternalKeySlot:
 *
 * Gets internal NSS key slot.
 *
 * Returns: internal key slot and initializes it if needed.
 */
PK11SlotInfo *
xmlSecNssGetInternalKeySlot()
{
    PK11SlotInfo *slot = NULL;
    SECStatus rv;

    slot = PK11_GetInternalKeySlot();
    if (slot == NULL) {
        xmlSecNssError("PK11_GetInternalKeySlot", NULL);
        return NULL;
    }

    if (PK11_NeedUserInit(slot)) {
        rv = PK11_InitPin(slot, NULL, NULL);
        if (rv != SECSuccess) {
            xmlSecNssError("PK11_InitPin", NULL);
            return NULL;
        }
    }

    if(PK11_IsLoggedIn(slot, NULL) != PR_TRUE) {
        rv = PK11_Authenticate(slot, PR_TRUE, NULL);
        if (rv != SECSuccess) {
            xmlSecNssError2("PK11_Authenticate", NULL,
                            "token=%s", xmlSecErrorsSafeString(PK11_GetTokenName(slot)));
            return NULL;
        }
    }

    return(slot);
}
Example #6
0
static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
                             char *key_file)
{
  PK11SlotInfo *slot;
  SECStatus status;
  CURLcode rv;
  struct ssl_connect_data *ssl = conn->ssl;
  (void)sockindex; /* unused */

  rv = nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE);
  if(CURLE_OK != rv) {
    PR_SetError(SEC_ERROR_BAD_KEY, 0);
    return rv;
  }

  slot = PK11_FindSlotByName("PEM Token #1");
  if(!slot)
    return CURLE_SSL_CERTPROBLEM;

  /* This will force the token to be seen as re-inserted */
  SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
  PK11_IsPresent(slot);

  status = PK11_Authenticate(slot, PR_TRUE,
                             conn->data->set.str[STRING_KEY_PASSWD]);
  PK11_FreeSlot(slot);
  return (SECSuccess == status)
    ? CURLE_OK
    : CURLE_SSL_CERTPROBLEM;
}
Example #7
0
/*
 * Authenticate to "unfriendly" tokens (tokens which need to be logged
 * in to find the certs.
 */
SECStatus
pk11_AuthenticateUnfriendly(PK11SlotInfo *slot, PRBool loadCerts, void *wincx)
{
    SECStatus rv = SECSuccess;
    if (!PK11_IsFriendly(slot)) {
	rv = PK11_Authenticate(slot, loadCerts, wincx);
    }
    return rv;
}
Example #8
0
int pkcs11_login(pkcs11_handle_t *h, char *password)
{
  SECStatus rv;

  if (h->slot == NULL) {
    DBG("Login failed: No Slot selected");
    return -1;
  }
  rv = PK11_Authenticate(h->slot, PR_FALSE, password);
  if (rv != SECSuccess) {
    DBG1("Login failed: %s", SECU_Strerror(PR_GetError()));
  }
  return (rv == SECSuccess) ? 0 : -1;
}
Example #9
0
static SECStatus nss_Init_Tokens(struct connectdata * conn)
{
  PK11SlotList *slotList;
  PK11SlotListElement *listEntry;
  SECStatus ret, status = SECSuccess;
  pphrase_arg_t *parg = NULL;

  parg = (pphrase_arg_t *) malloc(sizeof(*parg));
  parg->retryCount = 0;
  parg->data = conn->data;

  PK11_SetPasswordFunc(nss_get_password);

  slotList =
    PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, NULL);

  for(listEntry = PK11_GetFirstSafe(slotList);
      listEntry; listEntry = listEntry->next) {
    PK11SlotInfo *slot = listEntry->slot;

    if(PK11_NeedLogin(slot) && PK11_NeedUserInit(slot)) {
      if(slot == PK11_GetInternalKeySlot()) {
        failf(conn->data, "The NSS database has not been initialized.\n");
      }
      else {
        failf(conn->data, "The token %s has not been initialized.",
              PK11_GetTokenName(slot));
      }
      PK11_FreeSlot(slot);
      continue;
    }

    ret = PK11_Authenticate(slot, PR_TRUE, parg);
    if(SECSuccess != ret) {
      if (PR_GetError() == SEC_ERROR_BAD_PASSWORD)
        infof(conn->data, "The password for token '%s' is incorrect\n",
              PK11_GetTokenName(slot));
      status = SECFailure;
      break;
    }
    parg->retryCount = 0; /* reset counter to 0 for the next token */
    PK11_FreeSlot(slot);
  }

  free(parg);

  return status;
}
Example #10
0
NS_IMETHODIMP
nsPK11Token::Login(bool force)
{
  nsresult rv;
  bool test;
  rv = this->NeedsLogin(&test);
  if (NS_FAILED(rv)) return rv;
  if (test && force) {
    rv = this->LogoutSimple();
    if (NS_FAILED(rv)) return rv;
  }
  rv = setPassword(mSlot.get(), mUIContext);
  if (NS_FAILED(rv)) return rv;

  return MapSECStatus(PK11_Authenticate(mSlot.get(), true, mUIContext));
}
Example #11
0
/* Generate a key pair, and then generate a subjectPublicKeyInfo
** for the public key in that pair.  return all 3.
*/
CERTSubjectPublicKeyInfo *
GetSubjectPubKeyInfo(TESTKeyPair *pair)
{
    CERTSubjectPublicKeyInfo *spki       = NULL;
    SECKEYPrivateKey         *privKey    = NULL;
    SECKEYPublicKey          *pubKey     = NULL;
    PK11SlotInfo             *keySlot    = NULL;
    
    keySlot = PK11_GetInternalKeySlot();
    PK11_Authenticate(keySlot, PR_FALSE, &pwdata);


    if (!doingDSA) {
	PK11RSAGenParams *rsaParams = GetRSAParams();
	if (rsaParams == NULL) {
	    PK11_FreeSlot(keySlot);
	    return NULL;
	}
	privKey = PK11_GenerateKeyPair(keySlot, CKM_RSA_PKCS_KEY_PAIR_GEN,
				       (void*)rsaParams, &pubKey, PR_FALSE,
				       PR_FALSE, &pwdata);
    } else {
	PQGParams *dsaParams = GetDSAParams();
	if (dsaParams == NULL) {
	    PK11_FreeSlot(keySlot);
	    return NULL;
	}
	privKey = PK11_GenerateKeyPair(keySlot, CKM_DSA_KEY_PAIR_GEN,
				       (void*)dsaParams, &pubKey, PR_FALSE,
				       PR_FALSE, &pwdata);
    }
    PK11_FreeSlot(keySlot);
    if (privKey == NULL || pubKey == NULL) {
        if (pubKey) {
	    SECKEY_DestroyPublicKey(pubKey);
	}
	if (privKey) {
	    SECKEY_DestroyPrivateKey(privKey);
	}
	return NULL;
    }

    spki = SECKEY_CreateSubjectPublicKeyInfo(pubKey);
    pair->privKey = privKey;
    pair->pubKey  = pubKey;
    return spki;
}
gboolean
msd_smartcard_unlock (MsdSmartcard *card,
                      const char   *password)
{
        SECStatus status;

        PK11_SetPasswordFunc ((PK11PasswordFunc) msd_smartcard_password_handler);

        /* we pass PR_TRUE to load certificates
        */
        status = PK11_Authenticate (card->priv->slot, PR_TRUE, (gpointer) password);

        if (status != SECSuccess) {
                g_debug ("could not unlock card - %d", status);
                return FALSE;
        }
        return TRUE;
}
Example #13
0
/* [noscript] long encrypt (in buffer data, in long dataLen, out buffer result); */
NS_IMETHODIMP nsSecretDecoderRing::
Encrypt(unsigned char * data, PRInt32 dataLen, unsigned char * *result, PRInt32 *_retval)
{
  nsNSSShutDownPreventionLock locker;
  nsresult rv = NS_OK;
  PK11SlotInfo *slot = 0;
  PK11SlotInfoCleaner tmpSlotCleaner(slot);
  SECItem keyid;
  SECItem request;
  SECItem reply;
  SECStatus s;
  nsCOMPtr<nsIInterfaceRequestor> ctx = new nsSDRContext();
  if (!ctx) { rv = NS_ERROR_OUT_OF_MEMORY; goto loser; }

  slot = PK11_GetInternalKeySlot();
  if (!slot) { rv = NS_ERROR_NOT_AVAILABLE; goto loser; }

  /* Make sure token is initialized. */
  rv = setPassword(slot, ctx);
  if (NS_FAILED(rv))
    goto loser;

  /* Force authentication */
  s = PK11_Authenticate(slot, true, ctx);
  if (s != SECSuccess) { rv = NS_ERROR_FAILURE; goto loser; }

  /* Use default key id */
  keyid.data = 0;
  keyid.len = 0;
  request.data = data;
  request.len = dataLen;
  reply.data = 0;
  reply.len = 0;
  s= PK11SDR_Encrypt(&keyid, &request, &reply, ctx);
  if (s != SECSuccess) { rv = NS_ERROR_FAILURE; goto loser; }

  *result = reply.data;
  *_retval = reply.len;

loser:
  return rv;
}
Example #14
0
PK11SlotInfo *lsw_nss_get_authenticated_slot(lsw_nss_buf_t err)
{
	PK11SlotInfo *slot = PK11_GetInternalKeySlot();
	if (slot == NULL) {
		snprintf(err, sizeof(lsw_nss_buf_t), "no internal key slot");
		return NULL;
	}

	if (PK11_IsFIPS() || PK11_NeedLogin(slot)) {
		SECStatus status = PK11_Authenticate(slot, PR_FALSE,
						     lsw_return_nss_password_file_info());
		if (status != SECSuccess) {
			const char *token = PK11_GetTokenName(slot);
			snprintf(err, sizeof(lsw_nss_buf_t), "authentication of \"%s\" failed", token);
			PK11_FreeSlot(slot);
			return NULL;
		}
	}
	return slot;
}
Example #15
0
static SECStatus nss_Init_Tokens(struct connectdata * conn)
{
  PK11SlotList *slotList;
  PK11SlotListElement *listEntry;
  SECStatus ret, status = SECSuccess;

  PK11_SetPasswordFunc(nss_get_password);

  slotList =
    PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, NULL);

  for(listEntry = PK11_GetFirstSafe(slotList);
      listEntry; listEntry = listEntry->next) {
    PK11SlotInfo *slot = listEntry->slot;

    if(PK11_NeedLogin(slot) && PK11_NeedUserInit(slot)) {
      if(slot == PK11_GetInternalKeySlot()) {
        failf(conn->data, "The NSS database has not been initialized");
      }
      else {
        failf(conn->data, "The token %s has not been initialized",
              PK11_GetTokenName(slot));
      }
      PK11_FreeSlot(slot);
      continue;
    }

    ret = PK11_Authenticate(slot, PR_TRUE,
                            conn->data->set.str[STRING_KEY_PASSWD]);
    if(SECSuccess != ret) {
      if(PR_GetError() == SEC_ERROR_BAD_PASSWORD)
        infof(conn->data, "The password for token '%s' is incorrect\n",
              PK11_GetTokenName(slot));
      status = SECFailure;
      break;
    }
    PK11_FreeSlot(slot);
  }

  return status;
}
Example #16
0
NS_IMETHODIMP 
nsPK11Token::Login(bool force)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown())
    return NS_ERROR_NOT_AVAILABLE;

  nsresult rv;
  SECStatus srv;
  bool test;
  rv = this->NeedsLogin(&test);
  if (NS_FAILED(rv)) return rv;
  if (test && force) {
    rv = this->LogoutSimple();
    if (NS_FAILED(rv)) return rv;
  }
  rv = setPassword(mSlot, mUIContext, locker);
  if (NS_FAILED(rv)) return rv;
  srv = PK11_Authenticate(mSlot, true, mUIContext);
  return (srv == SECSuccess) ? NS_OK : NS_ERROR_FAILURE;
}
Example #17
0
/* [noscript] long decrypt (in buffer data, in long dataLen, out buffer result); */
NS_IMETHODIMP nsSecretDecoderRing::
Decrypt(unsigned char * data, PRInt32 dataLen, unsigned char * *result, PRInt32 *_retval)
{
  nsNSSShutDownPreventionLock locker;
  nsresult rv = NS_OK;
  PK11SlotInfo *slot = 0;
  PK11SlotInfoCleaner tmpSlotCleaner(slot);
  SECStatus s;
  SECItem request;
  SECItem reply;
  nsCOMPtr<nsIInterfaceRequestor> ctx = new nsSDRContext();
  if (!ctx) { rv = NS_ERROR_OUT_OF_MEMORY; goto loser; }

  *result = 0;
  *_retval = 0;

  /* Find token with SDR key */
  slot = PK11_GetInternalKeySlot();
  if (!slot) { rv = NS_ERROR_NOT_AVAILABLE; goto loser; }

  /* Force authentication */
  if (PK11_Authenticate(slot, true, ctx) != SECSuccess)
  {
    rv = NS_ERROR_NOT_AVAILABLE;
    goto loser;
  }

  request.data = data;
  request.len = dataLen;
  reply.data = 0;
  reply.len = 0;
  s = PK11SDR_Decrypt(&request, &reply, ctx);
  if (s != SECSuccess) { rv = NS_ERROR_FAILURE; goto loser; }

  *result = reply.data;
  *_retval = reply.len;

loser:
  return rv;
}
Example #18
0
static CERTCertList *get_all_root_certs(void)
{
	PK11SlotInfo *slot = PK11_GetInternalKeySlot();

	if (slot == NULL)
		return NULL;

	if (PK11_NeedLogin(slot)) {
		SECStatus rv = PK11_Authenticate(slot, PR_TRUE,
				lsw_return_nss_password_file_info());
		if (rv != SECSuccess)
			return NULL;
	}

	CERTCertList *allcerts = PK11_ListCertsInSlot(slot);

	if (allcerts == NULL)
		return NULL;

	CERTCertList *roots = CERT_NewCertList();

	CERTCertListNode *node;

	for (node = CERT_LIST_HEAD(allcerts); !CERT_LIST_END(node, allcerts);
						node = CERT_LIST_NEXT(node)) {
		if (CERT_IsCACert(node->cert, NULL) && node->cert->isRoot) {
			CERT_DupCertificate(node->cert);
			CERT_AddCertToListTail(roots, node->cert);
		}
	}

	CERT_DestroyCertList(allcerts);

	if (roots == NULL || CERT_LIST_EMPTY(roots))
		return NULL;

	return roots;
}
Example #19
0
nsresult
nsNSSCertificate::MarkForPermDeletion()
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown())
    return NS_ERROR_NOT_AVAILABLE;

  // make sure user is logged in to the token
  nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();

  if (PK11_NeedLogin(mCert->slot)
      && !PK11_NeedUserInit(mCert->slot)
      && !PK11_IsInternal(mCert->slot))
  {
    if (SECSuccess != PK11_Authenticate(mCert->slot, true, ctx))
    {
      return NS_ERROR_FAILURE;
    }
  }

  mPermDelete = true;
  return NS_OK;
}
Example #20
0
PK11SymKey *
FindKey(PK11SlotInfo *slot, char *name, SECItem *id, void *pwd)
{
    PK11SymKey *key = NULL;
    SECStatus rv = PK11_Authenticate(slot, PR_FALSE, pwd);

    if (rv != SECSuccess) {
	return NULL;
    }


    if (id->data) {
	key = PK11_FindFixedKey(slot,CKM_INVALID_MECHANISM, id, pwd);
    }
    if (name && !key) {
	key = PK11_ListFixedKeysInSlot(slot,name, pwd);
    }

    if (key) {
	printf("Found a key\n");
	PrintKey(key);
    }
    return key;
}
Example #21
0
SECStatus
ListKeys(PK11SlotInfo *slot, int *printLabel, void *pwd) {
    PK11SymKey *keyList;
    SECStatus rv = PK11_Authenticate(slot, PR_FALSE, pwd);
    if (rv != SECSuccess) {
        return rv;;
    }

    keyList = PK11_ListFixedKeysInSlot(slot, NULL, pwd);
    if (keyList) {
	if (*printLabel) {
            printf("     Name            Len Strength     Type    Data\n");
	    *printLabel = 0;
	}
	printf("%s:\n",PK11_GetTokenName(slot));
    }
    while (keyList) {
        PK11SymKey *freeKey = keyList;
        PrintKey(keyList);
        keyList = PK11_GetNextSymKey(keyList);
        PK11_FreeSymKey(freeKey);
    }
    return SECSuccess;
}
Example #22
0
/* login into the card, return the 7816 status word (sw2 || sw1) */
vcard_7816_status_t
vcard_emul_login(VCard *card, unsigned char *pin, int pin_len)
{
    PK11SlotInfo *slot;
    unsigned char *pin_string = NULL;
    int i;
    SECStatus rv;

    if (!nss_emul_init) {
        return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;
    }
    slot = vcard_emul_card_get_slot(card);
     /* We depend on the PKCS #11 module internal login state here because we
      * create a separate process to handle each guest instance. If we needed
      * to handle multiple guests from one process, then we would need to keep
      * a lot of extra state in our card structure
      * */
    pin_string = g_malloc(pin_len+1);
    memcpy(pin_string, pin, pin_len);
    pin_string[pin_len] = 0;

    /* handle CAC expanded pins correctly */
    for (i = pin_len-1; i >= 0 && (pin_string[i] == 0xff); i--) {
        pin_string[i] = 0;
    }

    rv = PK11_Authenticate(slot, PR_FALSE, pin_string);
    memset(pin_string, 0, pin_len);  /* don't let the pin hang around in memory
                                        to be snooped */
    g_free(pin_string);
    if (rv == SECSuccess) {
        return VCARD7816_STATUS_SUCCESS;
    }
    /* map the error from port get error */
    return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;
}
Example #23
0
int sign_hash(const struct RSA_private_key *k
              , const u_char *hash_val, size_t hash_len
              , u_char *sig_val, size_t sig_len)
{
    SECKEYPrivateKey *privateKey = NULL;
    SECItem signature;
    SECItem data;
    SECItem ckaId;
    PK11SlotInfo *slot = NULL;

    DBG(DBG_CRYPT, DBG_log("RSA_sign_hash: Started using NSS"));

    ckaId.type=siBuffer;
    ckaId.len = k->ckaid_len;
    ckaId.data = DISCARD_CONST(unsigned char *, k->ckaid);

    slot = PK11_GetInternalKeySlot();
    if (slot == NULL) {
	loglog(RC_LOG_SERIOUS, "RSA_sign_hash: Unable to find (slot security) device (err %d)\n", PR_GetError());
	return 0;
    }

    if( PK11_Authenticate(slot, PR_FALSE,osw_return_nss_password_file_info()) == SECSuccess ) {
	DBG(DBG_CRYPT, DBG_log("NSS: Authentication to NSS successful\n"));
    }
    else {
	DBG(DBG_CRYPT, DBG_log("NSS: Authentication to NSS either failed or not required,if NSS DB without password\n"));
    }

    privateKey = PK11_FindKeyByKeyID(slot, &ckaId, osw_return_nss_password_file_info());
    if(privateKey==NULL) {
        DBG(DBG_CRYPT,
            DBG_log("Can't find the private key from the NSS CKA_ID"));
	if(k->pub.nssCert != NULL) {
	   privateKey = PK11_FindKeyByAnyCert(k->pub.nssCert,  osw_return_nss_password_file_info());
           if (privateKey == NULL) {
               loglog(RC_LOG_SERIOUS,
                      "Can't find the private key from the NSS CERT (err %d)",
                      PR_GetError());
           }
	}
    }

    PK11_FreeSlot(slot);

    if (privateKey == NULL) {
	loglog(RC_LOG_SERIOUS, "Can't find the private key from the NSS CERT (err %d)\n", PR_GetError());
	return 0;
    }

    data.type=siBuffer;
    data.len=hash_len;
    data.data = DISCARD_CONST(u_char *, hash_val);

    /*signature.len=PK11_SignatureLen(privateKey);*/
    signature.len=sig_len;
    signature.data=sig_val;

    {
        SECStatus s = PK11_Sign(privateKey, &signature, &data);

        if (s != SECSuccess) {
            loglog(RC_LOG_SERIOUS,
                   "RSA_sign_hash: sign function failed (%d)",
                   PR_GetError());
            return 0;
        }
    }

    DBG(DBG_CRYPT, DBG_log("RSA_sign_hash: Ended using NSS"));
    return signature.len;
}
Example #24
0
static SECStatus
SignAndStoreCrl(CERTSignedCrl *signCrl, CERTCertificate *cert,
                char *outFileName, SECOidTag hashAlgTag, int ascii,
                char *slotName, char *url, secuPWData *pwdata)
{
    PK11SlotInfo *slot = NULL;
    PRFileDesc   *outFile = NULL;
    SECStatus rv;
    SignAndEncodeFuncExitStat errCode;

    PORT_Assert(signCrl && (!ascii || outFileName));
    if (!signCrl || (ascii && !outFileName)) {
        SECU_PrintError(progName, "invalid args for function "
                        "SignAndStoreCrl\n");
        return SECFailure;
    }

    if (!slotName || !PL_strcmp(slotName, "internal"))
	slot = PK11_GetInternalKeySlot();
    else
	slot = PK11_FindSlotByName(slotName);
    if (!slot) {
	SECU_PrintError(progName, "can not find requested slot");
	return SECFailure;
    }

    if (PK11_NeedLogin(slot)) {
        rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
	if (rv != SECSuccess)
	    goto loser;
    }

    rv = SECU_SignAndEncodeCRL(cert, signCrl, hashAlgTag, &errCode);
    if (rv != SECSuccess) {
        char* errMsg = NULL;
        switch (errCode)
        {
            case noKeyFound:
                errMsg = "No private key found of signing cert";
                break;

            case noSignatureMatch:
                errMsg = "Key and Algorithm OId are do not match";
                break;

            default:
            case failToEncode:
                errMsg = "Failed to encode crl structure";
                break;

            case failToSign:
                errMsg = "Failed to sign crl structure";
                break;

            case noMem:
                errMsg = "Can not allocate memory";
                break;
        }
	SECU_PrintError(progName, "%s\n", errMsg);
	goto loser;
    }

    if (outFileName) {
	outFile = PR_Open(outFileName, PR_WRONLY|PR_CREATE_FILE, PR_IRUSR | PR_IWUSR);
	if (!outFile) {
	    SECU_PrintError(progName, "unable to open \"%s\" for writing\n",
			    outFileName);
	    goto loser;
	}
    }

    rv = SECU_StoreCRL(slot, signCrl->derCrl, outFile, ascii, url);
    if (rv != SECSuccess) {
        SECU_PrintError(progName, "fail to save CRL\n");
    }

  loser:
    if (outFile)
	PR_Close(outFile);
    if (slot)
	PK11_FreeSlot(slot);
    return rv;
}
Example #25
0
SECStatus ImportCRL (CERTCertDBHandle *certHandle, char *url, int type, 
                     PRFileDesc *inFile, PRInt32 importOptions, PRInt32 decodeOptions,
                     secuPWData *pwdata)
{
    CERTSignedCrl *crl = NULL;
    SECItem crlDER;
    PK11SlotInfo* slot = NULL;
    int rv;
#if defined(DEBUG_jp96085)
    PRIntervalTime starttime, endtime, elapsed;
    PRUint32 mins, secs, msecs;
#endif

    crlDER.data = NULL;


    /* Read in the entire file specified with the -f argument */
    rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE, PR_FALSE);
    if (rv != SECSuccess) {
	SECU_PrintError(progName, "unable to read input file");
	return (SECFailure);
    }

    decodeOptions |= CRL_DECODE_DONT_COPY_DER;

    slot = PK11_GetInternalKeySlot();

    if (PK11_NeedLogin(slot)) {
	rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
    if (rv != SECSuccess)
	goto loser;
    }
 
#if defined(DEBUG_jp96085)
    starttime = PR_IntervalNow();
#endif
    crl = PK11_ImportCRL(slot, &crlDER, url, type,
          NULL, importOptions, NULL, decodeOptions);
#if defined(DEBUG_jp96085)
    endtime = PR_IntervalNow();
    elapsed = endtime - starttime;
    mins = PR_IntervalToSeconds(elapsed) / 60;
    secs = PR_IntervalToSeconds(elapsed) % 60;
    msecs = PR_IntervalToMilliseconds(elapsed) % 1000;
    printf("Elapsed : %2d:%2d.%3d\n", mins, secs, msecs);
#endif
    if (!crl) {
	const char *errString;

	rv = SECFailure;
	errString = SECU_Strerror(PORT_GetError());
	if ( errString && PORT_Strlen (errString) == 0)
	    SECU_PrintError (progName, 
	        "CRL is not imported (error: input CRL is not up to date.)");
	else    
	    SECU_PrintError (progName, "unable to import CRL");
    } else {
	SEC_DestroyCrl (crl);
    }
  loser:
    if (slot) {
        PK11_FreeSlot(slot);
    }
    return (rv);
}
Example #26
0
nsresult
nsKeygenFormProcessor::GetPublicKey(const nsAString& aValue,
                                    const nsAString& aChallenge,
                                    const nsAFlatString& aKeyType,
                                    nsAString& aOutPublicKey,
                                    const nsAString& aKeyParams)
{
    nsNSSShutDownPreventionLock locker;
    if (isAlreadyShutDown()) {
      return NS_ERROR_NOT_AVAILABLE;
    }

    nsresult rv = NS_ERROR_FAILURE;
    char *keystring = nullptr;
    char *keyparamsString = nullptr;
    uint32_t keyGenMechanism;
    PK11SlotInfo *slot = nullptr;
    PK11RSAGenParams rsaParams;
    SECOidTag algTag;
    int keysize = 0;
    void *params = nullptr;
    SECKEYPrivateKey *privateKey = nullptr;
    SECKEYPublicKey *publicKey = nullptr;
    CERTSubjectPublicKeyInfo *spkInfo = nullptr;
    SECStatus srv = SECFailure;
    SECItem spkiItem;
    SECItem pkacItem;
    SECItem signedItem;
    CERTPublicKeyAndChallenge pkac;
    pkac.challenge.data = nullptr;
    nsIGeneratingKeypairInfoDialogs * dialogs;
    nsKeygenThread *KeygenRunnable = 0;
    nsCOMPtr<nsIKeygenThread> runnable;

    // permanent and sensitive flags for keygen
    PK11AttrFlags attrFlags = PK11_ATTR_TOKEN | PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE;

    UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
    if (!arena) {
        goto loser;
    }

    // Get the key size //
    for (size_t i = 0; i < number_of_key_size_choices; ++i) {
        if (aValue.Equals(mSECKeySizeChoiceList[i].name)) {
            keysize = mSECKeySizeChoiceList[i].size;
            break;
        }
    }
    if (!keysize) {
        goto loser;
    }

    // Set the keygen mechanism
    if (aKeyType.IsEmpty() || aKeyType.LowerCaseEqualsLiteral("rsa")) {
        keyGenMechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
    } else if (aKeyType.LowerCaseEqualsLiteral("ec")) {
        keyparamsString = ToNewCString(aKeyParams);
        if (!keyparamsString) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            goto loser;
        }

        keyGenMechanism = CKM_EC_KEY_PAIR_GEN;
        /* ecParams are initialized later */
    } else {
        goto loser;
    }

    // Get the slot
    rv = GetSlot(keyGenMechanism, &slot);
    if (NS_FAILED(rv)) {
        goto loser;
    }
    switch (keyGenMechanism) {
        case CKM_RSA_PKCS_KEY_PAIR_GEN:
            rsaParams.keySizeInBits = keysize;
            rsaParams.pe = DEFAULT_RSA_KEYGEN_PE;
            algTag = DEFAULT_RSA_KEYGEN_ALG;
            params = &rsaParams;
            break;
        case CKM_EC_KEY_PAIR_GEN:
            /* XXX We ought to rethink how the KEYGEN tag is 
             * displayed. The pulldown selections presented
             * to the user must depend on the keytype.
             * The displayed selection could be picked
             * from the keyparams attribute (this is currently called
             * the pqg attribute).
             * For now, we pick ecparams from the keyparams field
             * if it specifies a valid supported curve, or else 
             * we pick one of secp384r1, secp256r1 or secp192r1
             * respectively depending on the user's selection
             * (High, Medium, Low). 
             * (RSA uses RSA-2048, RSA-1024 and RSA-512 for historical
             * reasons, while ECC choices represent a stronger mapping)
             * NOTE: The user's selection
             * is silently ignored when a valid curve is presented
             * in keyparams.
             */
            if ((params = decode_ec_params(keyparamsString)) == nullptr) {
                /* The keyparams attribute did not specify a valid
                 * curve name so use a curve based on the keysize.
                 * NOTE: Here keysize is used only as an indication of
                 * High/Medium/Low strength; elliptic curve
                 * cryptography uses smaller keys than RSA to provide
                 * equivalent security.
                 */
                switch (keysize) {
                case 2048:
                    params = decode_ec_params("secp384r1");
                    break;
                case 1024:
                case 512:
                    params = decode_ec_params("secp256r1");
                    break;
                } 
            }
            /* XXX The signature algorithm ought to choose the hashing
             * algorithm based on key size once ECDSA variations based
             * on SHA256 SHA384 and SHA512 are standardized.
             */
            algTag = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
            break;
      default:
          goto loser;
      }

    /* Make sure token is initialized. */
    rv = setPassword(slot, m_ctx, locker);
    if (NS_FAILED(rv))
        goto loser;

    srv = PK11_Authenticate(slot, true, m_ctx);
    if (srv != SECSuccess) {
        goto loser;
    }

    rv = getNSSDialogs((void**)&dialogs,
                       NS_GET_IID(nsIGeneratingKeypairInfoDialogs),
                       NS_GENERATINGKEYPAIRINFODIALOGS_CONTRACTID);

    if (NS_SUCCEEDED(rv)) {
        KeygenRunnable = new nsKeygenThread();
        NS_IF_ADDREF(KeygenRunnable);
    }

    if (NS_FAILED(rv) || !KeygenRunnable) {
        rv = NS_OK;
        privateKey = PK11_GenerateKeyPairWithFlags(slot, keyGenMechanism, params,
                                                   &publicKey, attrFlags, m_ctx);
    } else {
        KeygenRunnable->SetParams( slot, attrFlags, nullptr, 0,
                                   keyGenMechanism, params, m_ctx );

        runnable = do_QueryInterface(KeygenRunnable);
        
        if (runnable) {
            rv = dialogs->DisplayGeneratingKeypairInfo(m_ctx, runnable);
            // We call join on the thread so we can be sure that no
            // simultaneous access to the passed parameters will happen.
            KeygenRunnable->Join();

            NS_RELEASE(dialogs);
            if (NS_SUCCEEDED(rv)) {
                PK11SlotInfo *used_slot = nullptr;
                rv = KeygenRunnable->ConsumeResult(&used_slot, &privateKey, &publicKey);
                if (NS_SUCCEEDED(rv) && used_slot) {
                  PK11_FreeSlot(used_slot);
                }
            }
        }
    }
    
    if (NS_FAILED(rv) || !privateKey) {
        goto loser;
    }
    // just in case we'll need to authenticate to the db -jp //
    privateKey->wincx = m_ctx;

    /*
     * Create a subject public key info from the public key.
     */
    spkInfo = SECKEY_CreateSubjectPublicKeyInfo(publicKey);
    if ( !spkInfo ) {
        goto loser;
    }

    /*
     * Now DER encode the whole subjectPublicKeyInfo.
     */
    srv = DER_Encode(arena.get(), &spkiItem, CERTSubjectPublicKeyInfoTemplate,
                     spkInfo);
    if (srv != SECSuccess) {
        goto loser;
    }

    /*
     * set up the PublicKeyAndChallenge data structure, then DER encode it
     */
    pkac.spki = spkiItem;
    pkac.challenge.len = aChallenge.Length();
    pkac.challenge.data = (unsigned char *)ToNewCString(aChallenge);
    if (!pkac.challenge.data) {
        rv = NS_ERROR_OUT_OF_MEMORY;
        goto loser;
    }

    srv = DER_Encode(arena.get(), &pkacItem, CERTPublicKeyAndChallengeTemplate,
                     &pkac);
    if (srv != SECSuccess) {
        goto loser;
    }

    /*
     * now sign the DER encoded PublicKeyAndChallenge
     */
    srv = SEC_DerSignData(arena.get(), &signedItem, pkacItem.data, pkacItem.len,
                          privateKey, algTag);
    if (srv != SECSuccess) {
        goto loser;
    }

    /*
     * Convert the signed public key and challenge into base64/ascii.
     */
    keystring = BTOA_DataToAscii(signedItem.data, signedItem.len);
    if (!keystring) {
        rv = NS_ERROR_OUT_OF_MEMORY;
        goto loser;
    }

    CopyASCIItoUTF16(keystring, aOutPublicKey);
    free(keystring);

    rv = NS_OK;

    GatherKeygenTelemetry(keyGenMechanism, keysize, keyparamsString);
loser:
    if (srv != SECSuccess) {
        if ( privateKey ) {
            PK11_DestroyTokenObject(privateKey->pkcs11Slot,privateKey->pkcs11ID);
        }
        if ( publicKey ) {
            PK11_DestroyTokenObject(publicKey->pkcs11Slot,publicKey->pkcs11ID);
        }
    }
    if ( spkInfo ) {
        SECKEY_DestroySubjectPublicKeyInfo(spkInfo);
    }
    if ( publicKey ) {
        SECKEY_DestroyPublicKey(publicKey);
    }
    if ( privateKey ) {
        SECKEY_DestroyPrivateKey(privateKey);
    }
    if (slot) {
        PK11_FreeSlot(slot);
    }
    if (KeygenRunnable) {
        NS_RELEASE(KeygenRunnable);
    }
    if (keyparamsString) {
        free(keyparamsString);
    }
    if (pkac.challenge.data) {
        free(pkac.challenge.data);
    }
    // If params is non-null and doesn't point to rsaParams, it was allocated
    // in decode_ec_params. We have to free this memory.
    if (params && params != &rsaParams) {
        SECITEM_FreeItem(static_cast<SECItem*>(params), true);
        params = nullptr;
    }
    return rv;
}
Example #27
0
int
main(int argc, char **argv)
{
    PLOptState *optstate;
    PLOptStatus optstatus;

    PRUint32 flags = 0;
    Error ret;
    SECStatus rv;
    char *dbString = NULL;
    PRBool doInitTest = PR_FALSE;
    int i;

    progName = strrchr(argv[0], '/');
    if (!progName)
        progName = strrchr(argv[0], '\\');
    progName = progName ? progName + 1 : argv[0];

    optstate = PL_CreateOptState(argc, argv, "rfip:d:h");

    while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
        switch (optstate->option) {
            case 'h':
            default:
                Usage(progName);
                break;

            case 'r':
                flags |= NSS_INIT_READONLY;
                break;

            case 'f':
                flags |= NSS_INIT_FORCEOPEN;
                break;

            case 'i':
                doInitTest = PR_TRUE;
                break;

            case 'p':
                userPassword = PORT_Strdup(optstate->value);
                break;

            case 'd':
                dbDir = PORT_Strdup(optstate->value);
                break;
        }
    }
    if (optstatus == PL_OPT_BAD)
        Usage(progName);

    if (!dbDir) {
        dbDir = SECU_DefaultSSLDir(); /* Look in $SSL_DIR */
    }
    dbDir = SECU_ConfigDirectory(dbDir);
    PR_fprintf(PR_STDERR, "dbdir selected is %s\n\n", dbDir);

    if (dbDir[0] == '\0') {
        PR_fprintf(PR_STDERR, errStrings[DIR_DOESNT_EXIST_ERR], dbDir);
        ret = DIR_DOESNT_EXIST_ERR;
        goto loser;
    }

    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);

    /* get the status of the directory and databases and output message */
    if (PR_Access(dbDir, PR_ACCESS_EXISTS) != PR_SUCCESS) {
        PR_fprintf(PR_STDERR, errStrings[DIR_DOESNT_EXIST_ERR], dbDir);
    } else if (PR_Access(dbDir, PR_ACCESS_READ_OK) != PR_SUCCESS) {
        PR_fprintf(PR_STDERR, errStrings[DIR_NOT_READABLE_ERR], dbDir);
    } else {
        if (!(flags & NSS_INIT_READONLY) &&
            PR_Access(dbDir, PR_ACCESS_WRITE_OK) != PR_SUCCESS) {
            PR_fprintf(PR_STDERR, errStrings[DIR_NOT_WRITEABLE_ERR], dbDir);
        }
        if (!doInitTest) {
            for (i = 0; i < 3; i++) {
                dbString = PR_smprintf("%s/%s", dbDir, dbName[i]);
                PR_fprintf(PR_STDOUT, "database checked is %s\n", dbString);
                if (PR_Access(dbString, PR_ACCESS_EXISTS) != PR_SUCCESS) {
                    PR_fprintf(PR_STDERR, errStrings[FILE_DOESNT_EXIST_ERR],
                               dbString);
                } else if (PR_Access(dbString, PR_ACCESS_READ_OK) != PR_SUCCESS) {
                    PR_fprintf(PR_STDERR, errStrings[FILE_NOT_READABLE_ERR],
                               dbString);
                } else if (!(flags & NSS_INIT_READONLY) &&
                           PR_Access(dbString, PR_ACCESS_WRITE_OK) != PR_SUCCESS) {
                    PR_fprintf(PR_STDERR, errStrings[FILE_NOT_WRITEABLE_ERR],
                               dbString);
                }
            }
        }
    }

    rv = NSS_Initialize(SECU_ConfigDirectory(dbDir), dbprefix, dbprefix,
                        secmodName, flags);
    if (rv != SECSuccess) {
        SECU_PrintPRandOSError(progName);
        ret = NSS_INITIALIZE_FAILED_ERR;
    } else {
        ret = SUCCESS;
        if (doInitTest) {
            PK11SlotInfo *slot = PK11_GetInternalKeySlot();
            SECStatus rv;
            int passwordSuccess = 0;
            int type = CKM_DES3_CBC;
            SECItem keyid = { 0, NULL, 0 };
            unsigned char keyIdData[] = { 0xff, 0xfe };
            PK11SymKey *key = NULL;

            keyid.data = keyIdData;
            keyid.len = sizeof(keyIdData);

            PK11_SetPasswordFunc(getPassword);
            rv = PK11_InitPin(slot, (char *)NULL, userPassword);
            if (rv != SECSuccess) {
                PR_fprintf(PR_STDERR, "Failed to Init DB: %s\n",
                           SECU_Strerror(PORT_GetError()));
                ret = CHANGEPW_FAILED_ERR;
            }
            if (*userPassword && !PK11_IsLoggedIn(slot, &passwordSuccess)) {
                PR_fprintf(PR_STDERR, "New DB did not log in after init\n");
                ret = AUTHENTICATION_FAILED_ERR;
            }
            /* generate a symetric key */
            key = PK11_TokenKeyGen(slot, type, NULL, 0, &keyid,
                                   PR_TRUE, &passwordSuccess);

            if (!key) {
                PR_fprintf(PR_STDERR, "Could not generated symetric key: %s\n",
                           SECU_Strerror(PORT_GetError()));
                exit(UNSPECIFIED_ERR);
            }
            PK11_FreeSymKey(key);
            PK11_Logout(slot);

            PK11_Authenticate(slot, PR_TRUE, &passwordSuccess);

            if (*userPassword && !passwordSuccess) {
                PR_fprintf(PR_STDERR, "New DB Did not initalize\n");
                ret = AUTHENTICATION_FAILED_ERR;
            }
            key = PK11_FindFixedKey(slot, type, &keyid, &passwordSuccess);

            if (!key) {
                PR_fprintf(PR_STDERR, "Could not find generated key: %s\n",
                           SECU_Strerror(PORT_GetError()));
                ret = UNSPECIFIED_ERR;
            } else {
                PK11_FreeSymKey(key);
            }
            PK11_FreeSlot(slot);
        }

        if (NSS_Shutdown() != SECSuccess) {
            PR_fprintf(PR_STDERR, "Could not find generated key: %s\n",
                       SECU_Strerror(PORT_GetError()));
            exit(1);
        }
    }

loser:
    return ret;
}
Example #28
0
/*
 * generate an RSA signature key
 *
 * e is fixed at 3, without discussion.  That would not be wise if these
 * keys were to be used for encryption, but for signatures there are some
 * real speed advantages.
 * See also: https://www.imperialviolet.org/2012/03/16/rsae.html
 */
void rsasigkey(int nbits, char *configdir, char *password)
{
	SECStatus rv;
	PK11RSAGenParams rsaparams      = { nbits, (long) E };
	secuPWData pwdata              = { PW_NONE, NULL };
	PK11SlotInfo *slot              = NULL;
	SECKEYPrivateKey *privkey       = NULL;
	SECKEYPublicKey *pubkey         = NULL;
	unsigned char *bundp            = NULL;
	mpz_t n;
	mpz_t e;
	size_t bs;
	char n_str[3 + MAXBITS / 4 + 1];
	realtime_t now = realnow();

	mpz_init(n);
	mpz_init(e);

	if (password == NULL) {
		pwdata.source = PW_NONE;
	} else {
		/* check if passwd == configdir/nsspassword */
		size_t cdl = strlen(configdir);
		size_t pwl = strlen(password);
		static const char suf[] = "/nsspassword";

		if (pwl == cdl + sizeof(suf) - 1 &&
			memeq(password, configdir, cdl) &&
			memeq(password + cdl, suf, sizeof(suf)))
			pwdata.source = PW_FROMFILE;
		else
			pwdata.source = PW_PLAINTEXT;
	}
	pwdata.data = password;

	PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 1);

	rv = NSS_InitReadWrite(configdir);
	if (rv != SECSuccess) {
		fprintf(stderr, "%s: NSS_InitReadWrite(%s) returned %d\n",
			me, configdir, PR_GetError());
		exit(1);
	}
#ifdef FIPS_CHECK
	if (PK11_IsFIPS() && !FIPSCHECK_verify(NULL, NULL)) {
		fprintf(stderr,
			"FIPS HMAC integrity verification test failed.\n");
		exit(1);
	}
#endif

	if (PK11_IsFIPS() && !password) {
		fprintf(stderr,
			"%s: On FIPS mode a password is required\n",
			me);
		exit(1);
	}

	PK11_SetPasswordFunc(GetModulePassword);

	/* Good for now but someone may want to use a hardware token */
	slot = PK11_GetInternalKeySlot();
	/* In which case this may be better */
	/* slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN, password ? &pwdata : NULL); */
	/* or the user may specify the name of a token. */

#if 0
	if (PK11_IsFIPS() || !PK11_IsInternal(slot)) {
		rv = PK11_Authenticate(slot, PR_FALSE, &pwdata);
		if (rv != SECSuccess) {
			fprintf(stderr, "%s: could not authenticate to token '%s'\n",
				me, PK11_GetTokenName(slot));
			return;
		}
	}
#endif /* 0 */

	/* Do some random-number initialization. */
	UpdateNSS_RNG();
	/* Log in to the token */
	if (password) {
		rv = PK11_Authenticate(slot, PR_FALSE, &pwdata);
		if (rv != SECSuccess) {
			fprintf(stderr,
				"%s: could not authenticate to token '%s'\n",
				me, PK11_GetTokenName(slot));
			return;
		}
	}
	privkey = PK11_GenerateKeyPair(slot,
				       CKM_RSA_PKCS_KEY_PAIR_GEN,
				       &rsaparams, &pubkey,
				       PR_TRUE,
				       password ? PR_TRUE : PR_FALSE,
				       &pwdata);
	/* inTheToken, isSensitive, passwordCallbackFunction */
	if (!privkey) {
		fprintf(stderr,
			"%s: key pair generation failed: \"%d\"\n", me,
			PORT_GetError());
		return;
	}

	/*privkey->wincx = &pwdata;*/
	PORT_Assert(pubkey != NULL);
	fprintf(stderr,
		"Generated RSA key pair using the NSS database\n");

	SECItemToHex(getModulus(pubkey), n_str);
	assert(!mpz_set_str(n, n_str, 16));

	/* and the output */
	report("output...\n");  /* deliberate extra newline */
	printf("\t# RSA %d bits   %s   %s", nbits, outputhostname,
		ctime(&now.real_secs));
	/* ctime provides \n */
	printf("\t# for signatures only, UNSAFE FOR ENCRYPTION\n");
	bundp = bundle(E, n, &bs);
	printf("\t#pubkey=%s\n", conv(bundp, bs, 's')); /* RFC2537ish format */
	printf("\tModulus: %s\n", hexOut(getModulus(pubkey)));
	printf("\tPublicExponent: %s\n",
	       hexOut(getPublicExponent(pubkey)));

	SECItem *ckaID = PK11_MakeIDFromPubKey(getModulus(pubkey));
	if (ckaID != NULL) {
		printf("\t# everything after this point is CKA_ID in hex format - not the real values \n");
		printf("\tPrivateExponent: %s\n", hexOut(ckaID));
		printf("\tPrime1: %s\n", hexOut(ckaID));
		printf("\tPrime2: %s\n", hexOut(ckaID));
		printf("\tExponent1: %s\n", hexOut(ckaID));
		printf("\tExponent2: %s\n", hexOut(ckaID));
		printf("\tCoefficient: %s\n", hexOut(ckaID));
		printf("\tCKAIDNSS: %s\n", hexOut(ckaID));
		SECITEM_FreeItem(ckaID, PR_TRUE);
	}

	if (privkey)
		SECKEY_DestroyPrivateKey(privkey);
	if (pubkey)
		SECKEY_DestroyPublicKey(pubkey);

	(void) NSS_Shutdown();
	(void) PR_Cleanup();
}
Example #29
0
/*
 * generate an RSA signature key
 *
 * e is fixed at 3, without discussion.  That would not be wise if these
 * keys were to be used for encryption, but for signatures there are some
 * real speed advantages.
 * See also: https://www.imperialviolet.org/2012/03/16/rsae.html
 */
void rsasigkey(int nbits, int seedbits, char *configdir, char *password)
{
	SECStatus rv;
	PK11RSAGenParams rsaparams = { nbits, (long) E };
	secuPWData pwdata = { PW_NONE, NULL };
	PK11SlotInfo *slot = NULL;
	SECKEYPrivateKey *privkey = NULL;
	SECKEYPublicKey *pubkey = NULL;
	realtime_t now = realnow();

	if (password == NULL) {
		pwdata.source = PW_NONE;
	} else {
		/* check if passwd == configdir/nsspassword */
		size_t cdl = strlen(configdir);
		size_t pwl = strlen(password);
		static const char suf[] = "/nsspassword";

		if (pwl == cdl + sizeof(suf) - 1 &&
			memeq(password, configdir, cdl) &&
			memeq(password + cdl, suf, sizeof(suf)))
			pwdata.source = PW_FROMFILE;
		else
			pwdata.source = PW_PLAINTEXT;
	}
	pwdata.data = password;

	lsw_nss_buf_t err;
	if (!lsw_nss_setup(configdir, FALSE/*rw*/, GetModulePassword, err)) {
		fprintf(stderr, "%s: %s\n", me, err);
		exit(1);
	}

#ifdef FIPS_CHECK
	if (PK11_IsFIPS() && !FIPSCHECK_verify(NULL, NULL)) {
		fprintf(stderr,
			"FIPS HMAC integrity verification test failed.\n");
		exit(1);
	}
#endif

	if (PK11_IsFIPS() && password == NULL) {
		fprintf(stderr,
			"%s: On FIPS mode a password is required\n",
			me);
		exit(1);
	}

	/* Good for now but someone may want to use a hardware token */
	slot = PK11_GetInternalKeySlot();
	/* In which case this may be better */
	/* slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN, password ? &pwdata : NULL); */
	/* or the user may specify the name of a token. */

#if 0
	if (PK11_IsFIPS() || !PK11_IsInternal(slot)) {
		rv = PK11_Authenticate(slot, PR_FALSE, &pwdata);
		if (rv != SECSuccess) {
			fprintf(stderr, "%s: could not authenticate to token '%s'\n",
				me, PK11_GetTokenName(slot));
			return;
		}
	}
#endif /* 0 */

	/* Do some random-number initialization. */
	UpdateNSS_RNG(seedbits);
	/* Log in to the token */
	if (password != NULL) {
		rv = PK11_Authenticate(slot, PR_FALSE, &pwdata);
		if (rv != SECSuccess) {
			fprintf(stderr,
				"%s: could not authenticate to token '%s'\n",
				me, PK11_GetTokenName(slot));
			return;
		}
	}
	privkey = PK11_GenerateKeyPair(slot,
				       CKM_RSA_PKCS_KEY_PAIR_GEN,
				       &rsaparams, &pubkey,
				       PR_TRUE,
				       password != NULL? PR_TRUE : PR_FALSE,
				       &pwdata);
	/* inTheToken, isSensitive, passwordCallbackFunction */
	if (privkey == NULL) {
		fprintf(stderr,
			"%s: key pair generation failed: \"%d\"\n", me,
			PORT_GetError());
		return;
	}

	chunk_t public_modulus = {
		.ptr = pubkey->u.rsa.modulus.data,
		.len = pubkey->u.rsa.modulus.len,
	};
	chunk_t public_exponent = {
		.ptr = pubkey->u.rsa.publicExponent.data,
		.len = pubkey->u.rsa.publicExponent.len,
	};

	char *hex_ckaid;
	{
		SECItem *ckaid = PK11_GetLowLevelKeyIDForPrivateKey(privkey);
		if (ckaid == NULL) {
			fprintf(stderr, "%s: 'CKAID' calculation failed\n", me);
			exit(1);
		}
		hex_ckaid = strdup(conv(ckaid->data, ckaid->len, 16));
		SECITEM_FreeItem(ckaid, PR_TRUE);
	}

	/*privkey->wincx = &pwdata;*/
	PORT_Assert(pubkey != NULL);
	fprintf(stderr, "Generated RSA key pair with CKAID %s was stored in the NSS database\n",
		hex_ckaid);

	/* and the output */
	report("output...\n");  /* deliberate extra newline */
	printf("\t# RSA %d bits   %s   %s", nbits, outputhostname,
		ctime(&now.real_secs));
	/* ctime provides \n */
	printf("\t# for signatures only, UNSAFE FOR ENCRYPTION\n");

	printf("\t#ckaid=%s\n", hex_ckaid);

	/* RFC2537/RFC3110-ish format */
	{
		char *bundle = base64_bundle(E, public_modulus);
		printf("\t#pubkey=%s\n", bundle);
		pfree(bundle);
	}

	printf("\tModulus: 0x%s\n", conv(public_modulus.ptr, public_modulus.len, 16));
	printf("\tPublicExponent: 0x%s\n", conv(public_exponent.ptr, public_exponent.len, 16));

	if (hex_ckaid != NULL)
		free(hex_ckaid);
	if (privkey != NULL)
		SECKEY_DestroyPrivateKey(privkey);
	if (pubkey != NULL)
		SECKEY_DestroyPublicKey(pubkey);

	lsw_nss_shutdown(LSW_NSS_CLEANUP);
}

/*
 * getrandom - get some random bytes from /dev/random (or wherever)
 * NOTE: This is only used for additional seeding of the NSS RNG
 */
void getrandom(size_t nbytes, unsigned char *buf)
{
	size_t ndone;
	int dev;
	ssize_t got;

	dev = open(device, 0);
	if (dev < 0) {
		fprintf(stderr, "%s: could not open %s (%s)\n", me,
			device, strerror(errno));
		exit(1);
	}

	ndone = 0;
	if (verbose) {
		fprintf(stderr, "getting %d random seed bytes for NSS from %s...\n",
			(int) nbytes * BITS_PER_BYTE,
			device);
	}
	while (ndone < nbytes) {
		got = read(dev, buf + ndone, nbytes - ndone);
		if (got < 0) {
			fprintf(stderr, "%s: read error on %s (%s)\n", me,
				device, strerror(errno));
			exit(1);
		}
		if (got == 0) {
			fprintf(stderr, "%s: eof on %s!?!\n", me, device);
			exit(1);
		}
		ndone += got;
	}

	close(dev);
}

/*
   - conv - convert bits to output in specified datatot format
 * NOTE: result points into a STATIC buffer
 */
static const char *conv(const unsigned char *bits, size_t nbytes, int format)
{
	static char convbuf[MAXBITS / 4 + 50];  /* enough for hex */
	size_t n;

	n = datatot(bits, nbytes, format, convbuf, sizeof(convbuf));
	if (n == 0) {
		fprintf(stderr, "%s: can't-happen convert error\n", me);
		exit(1);
	}
	if (n > sizeof(convbuf)) {
		fprintf(stderr,
			"%s: can't-happen convert overflow (need %d)\n",
			me, (int) n);
		exit(1);
	}
	return convbuf;
}

/*
   - report - report progress, if indicated
 */
void report(msg)
char *msg;
{
	if (!verbose)
		return;

	fprintf(stderr, "%s\n", msg);
}
Example #30
0
nsresult
nsKeygenFormProcessor::GetPublicKey(nsAString& aValue, nsAString& aChallenge,
                                    nsAFlatString& aKeyType,
                                    nsAString& aOutPublicKey, nsAString& aKeyParams)
{
    nsNSSShutDownPreventionLock locker;
    nsresult rv = NS_ERROR_FAILURE;
    char *keystring = nsnull;
    char *keyparamsString = nsnull, *str = nsnull;
    KeyType type;
    PRUint32 keyGenMechanism;
    PRInt32 primeBits;
    PK11SlotInfo *slot = nsnull;
    PK11RSAGenParams rsaParams;
    SECOidTag algTag;
    int keysize = 0;
    void *params;
    SECKEYPrivateKey *privateKey = nsnull;
    SECKEYPublicKey *publicKey = nsnull;
    CERTSubjectPublicKeyInfo *spkInfo = nsnull;
    PRArenaPool *arena = nsnull;
    SECStatus sec_rv = SECFailure;
    SECItem spkiItem;
    SECItem pkacItem;
    SECItem signedItem;
    CERTPublicKeyAndChallenge pkac;
    pkac.challenge.data = nsnull;
    nsIGeneratingKeypairInfoDialogs * dialogs;
    nsKeygenThread *KeygenRunnable = 0;
    nsCOMPtr<nsIKeygenThread> runnable;

    // Get the key size //
    for (size_t i = 0; i < number_of_key_size_choices; ++i) {
        if (aValue.Equals(mSECKeySizeChoiceList[i].name)) {
            keysize = mSECKeySizeChoiceList[i].size;
            break;
        }
    }
    if (!keysize) {
        goto loser;
    }

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena) {
        goto loser;
    }

    // Set the keygen mechanism
    if (aKeyType.IsEmpty() || aKeyType.LowerCaseEqualsLiteral("rsa")) {
        type = rsaKey;
        keyGenMechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
    } else if (aKeyType.LowerCaseEqualsLiteral("dsa")) {
        char * end;
        keyparamsString = ToNewCString(aKeyParams);
        if (!keyparamsString) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            goto loser;
        }

        type = dsaKey;
        keyGenMechanism = CKM_DSA_KEY_PAIR_GEN;
        if (strcmp(keyparamsString, "null") == 0)
            goto loser;
        str = keyparamsString;
        PRBool found_match = PR_FALSE;
        do {
            end = strchr(str, ',');
            if (end != nsnull)
                *end = '\0';
            primeBits = pqg_prime_bits(str);
            if (keysize == primeBits) {
                found_match = PR_TRUE;
                break;
            }
            str = end + 1;
        } while (end != nsnull);
        if (!found_match) {
            goto loser;
        }
    } else if (aKeyType.LowerCaseEqualsLiteral("ec")) {
        keyparamsString = ToNewCString(aKeyParams);
        if (!keyparamsString) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            goto loser;
        }

        type = ecKey;
        keyGenMechanism = CKM_EC_KEY_PAIR_GEN;
        /* ecParams are initialized later */
    } else {
        goto loser;
    }

    // Get the slot
    rv = GetSlot(keyGenMechanism, &slot);
    if (NS_FAILED(rv)) {
        goto loser;
    }
    switch (keyGenMechanism) {
    case CKM_RSA_PKCS_KEY_PAIR_GEN:
        rsaParams.keySizeInBits = keysize;
        rsaParams.pe = DEFAULT_RSA_KEYGEN_PE;
        algTag = DEFAULT_RSA_KEYGEN_ALG;
        params = &rsaParams;
        break;
    case CKM_DSA_KEY_PAIR_GEN:
        // XXX Fix this! XXX //
        goto loser;
    case CKM_EC_KEY_PAIR_GEN:
        /* XXX We ought to rethink how the KEYGEN tag is
         * displayed. The pulldown selections presented
         * to the user must depend on the keytype.
         * The displayed selection could be picked
         * from the keyparams attribute (this is currently called
         * the pqg attribute).
         * For now, we pick ecparams from the keyparams field
         * if it specifies a valid supported curve, or else
         * we pick one of secp384r1, secp256r1 or secp192r1
         * respectively depending on the user's selection
         * (High, Medium, Low).
         * (RSA uses RSA-2048, RSA-1024 and RSA-512 for historical
         * reasons, while ECC choices represent a stronger mapping)
         * NOTE: The user's selection
         * is silently ignored when a valid curve is presented
         * in keyparams.
         */
        if ((params = decode_ec_params(keyparamsString)) == nsnull) {
            /* The keyparams attribute did not specify a valid
             * curve name so use a curve based on the keysize.
             * NOTE: Here keysize is used only as an indication of
             * High/Medium/Low strength; elliptic curve
             * cryptography uses smaller keys than RSA to provide
             * equivalent security.
             */
            switch (keysize) {
            case 2048:
                params = decode_ec_params("secp384r1");
                break;
            case 1024:
            case 512:
                params = decode_ec_params("secp256r1");
                break;
            }
        }
        /* XXX The signature algorithm ought to choose the hashing
         * algorithm based on key size once ECDSA variations based
         * on SHA256 SHA384 and SHA512 are standardized.
         */
        algTag = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
        break;
    default:
        goto loser;
    }

    /* Make sure token is initialized. */
    rv = setPassword(slot, m_ctx);
    if (NS_FAILED(rv))
        goto loser;

    sec_rv = PK11_Authenticate(slot, PR_TRUE, m_ctx);
    if (sec_rv != SECSuccess) {
        goto loser;
    }

    rv = getNSSDialogs((void**)&dialogs,
                       NS_GET_IID(nsIGeneratingKeypairInfoDialogs),
                       NS_GENERATINGKEYPAIRINFODIALOGS_CONTRACTID);

    if (NS_SUCCEEDED(rv)) {
        KeygenRunnable = new nsKeygenThread();
        NS_IF_ADDREF(KeygenRunnable);
    }

    if (NS_FAILED(rv) || !KeygenRunnable) {
        rv = NS_OK;
        privateKey = PK11_GenerateKeyPair(slot, keyGenMechanism, params,
                                          &publicKey, PR_TRUE, PR_TRUE, m_ctx);
    } else {
        KeygenRunnable->SetParams( slot, keyGenMechanism, params, PR_TRUE, PR_TRUE, m_ctx );

        runnable = do_QueryInterface(KeygenRunnable);

        if (runnable) {
            {
                nsPSMUITracker tracker;
                if (tracker.isUIForbidden()) {
                    rv = NS_ERROR_NOT_AVAILABLE;
                }
                else {
                    rv = dialogs->DisplayGeneratingKeypairInfo(m_ctx, runnable);
                    // We call join on the thread,
                    // so we can be sure that no simultaneous access to the passed parameters will happen.
                    KeygenRunnable->Join();
                }
            }

            NS_RELEASE(dialogs);
            if (NS_SUCCEEDED(rv)) {
                rv = KeygenRunnable->GetParams(&privateKey, &publicKey);
            }
        }
    }

    if (NS_FAILED(rv) || !privateKey) {
        goto loser;
    }
    // just in case we'll need to authenticate to the db -jp //
    privateKey->wincx = m_ctx;

    /*
     * Create a subject public key info from the public key.
     */
    spkInfo = SECKEY_CreateSubjectPublicKeyInfo(publicKey);
    if ( !spkInfo ) {
        goto loser;
    }

    /*
     * Now DER encode the whole subjectPublicKeyInfo.
     */
    sec_rv=DER_Encode(arena, &spkiItem, CERTSubjectPublicKeyInfoTemplate, spkInfo);
    if (sec_rv != SECSuccess) {
        goto loser;
    }

    /*
     * set up the PublicKeyAndChallenge data structure, then DER encode it
     */
    pkac.spki = spkiItem;
    pkac.challenge.len = aChallenge.Length();
    pkac.challenge.data = (unsigned char *)ToNewCString(aChallenge);
    if (!pkac.challenge.data) {
        rv = NS_ERROR_OUT_OF_MEMORY;
        goto loser;
    }

    sec_rv = DER_Encode(arena, &pkacItem, CERTPublicKeyAndChallengeTemplate, &pkac);
    if ( sec_rv != SECSuccess ) {
        goto loser;
    }

    /*
     * now sign the DER encoded PublicKeyAndChallenge
     */
    sec_rv = SEC_DerSignData(arena, &signedItem, pkacItem.data, pkacItem.len,
                             privateKey, algTag);
    if ( sec_rv != SECSuccess ) {
        goto loser;
    }

    /*
     * Convert the signed public key and challenge into base64/ascii.
     */
    keystring = BTOA_DataToAscii(signedItem.data, signedItem.len);
    if (!keystring) {
        rv = NS_ERROR_OUT_OF_MEMORY;
        goto loser;
    }

    CopyASCIItoUTF16(keystring, aOutPublicKey);
    nsCRT::free(keystring);

    rv = NS_OK;
loser:
    if ( sec_rv != SECSuccess ) {
        if ( privateKey ) {
            PK11_DestroyTokenObject(privateKey->pkcs11Slot,privateKey->pkcs11ID);
        }
        if ( publicKey ) {
            PK11_DestroyTokenObject(publicKey->pkcs11Slot,publicKey->pkcs11ID);
        }
    }
    if ( spkInfo ) {
        SECKEY_DestroySubjectPublicKeyInfo(spkInfo);
    }
    if ( publicKey ) {
        SECKEY_DestroyPublicKey(publicKey);
    }
    if ( privateKey ) {
        SECKEY_DestroyPrivateKey(privateKey);
    }
    if ( arena ) {
        PORT_FreeArena(arena, PR_TRUE);
    }
    if (slot != nsnull) {
        PK11_FreeSlot(slot);
    }
    if (KeygenRunnable) {
        NS_RELEASE(KeygenRunnable);
    }
    if (keyparamsString) {
        nsMemory::Free(keyparamsString);
    }
    if (pkac.challenge.data) {
        nsMemory::Free(pkac.challenge.data);
    }
    return rv;
}