Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Protected Member Functions | Private Attributes
nsKeygenFormProcessor Class Reference

#include <nsKeygenHandler.h>

Inheritance diagram for nsKeygenFormProcessor:
Inheritance graph
[legend]
Collaboration diagram for nsKeygenFormProcessor:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsKeygenFormProcessor ()
virtual ~nsKeygenFormProcessor ()
nsresult Init ()
NS_IMETHOD ProcessValue (nsIDOMHTMLElement *aElement, const nsAString &aName, nsAString &aValue)
NS_IMETHOD ProvideContent (const nsAString &aFormType, nsVoidArray &aContent, nsAString &aAttribute)

Static Public Member Functions

static NS_DECL_ISUPPORTS NS_METHOD Create (nsISupports *aOuter, const nsIID &aIID, void **aResult)

Protected Member Functions

nsresult GetPublicKey (nsAString &aValue, nsAString &aChallenge, nsAFlatString &akeyType, nsAString &aOutPublicKey, nsAString &aPqg)
nsresult GetSlot (PRUint32 aMechanism, PK11SlotInfo **aSlot)

Private Attributes

nsCOMPtr< nsIInterfaceRequestorm_ctx

Detailed Description

Definition at line 58 of file nsKeygenHandler.h.


Constructor & Destructor Documentation

Definition at line 180 of file nsKeygenHandler.cpp.

Here is the caller graph for this function:

Definition at line 187 of file nsKeygenHandler.cpp.


Member Function Documentation

NS_METHOD nsKeygenFormProcessor::Create ( nsISupports *  aOuter,
const nsIID aIID,
void **  aResult 
) [static]

Definition at line 193 of file nsKeygenHandler.cpp.

{
  nsresult rv;
  NS_ENSURE_NO_AGGREGATION(aOuter);
  nsKeygenFormProcessor* formProc = new nsKeygenFormProcessor();
  if (!formProc)
    return NS_ERROR_OUT_OF_MEMORY;

  nsCOMPtr<nsISupports> stabilize = formProc;
  rv = formProc->Init();
  if (NS_SUCCEEDED(rv)) {
    rv = formProc->QueryInterface(aIID, aResult);
  }
  return rv;
}

Here is the call graph for this function:

nsresult nsKeygenFormProcessor::GetPublicKey ( nsAString &  aValue,
nsAString &  aChallenge,
nsAFlatString akeyType,
nsAString &  aOutPublicKey,
nsAString &  aPqg 
) [protected]

Definition at line 385 of file nsKeygenHandler.cpp.

{
    nsNSSShutDownPreventionLock locker;
    nsresult rv = NS_ERROR_FAILURE;
    char *keystring = nsnull;
    char *pqgString = nsnull, *str = nsnull;
    KeyType type;
    PRUint32 keyGenMechanism;
    PRInt32 primeBits;
    PQGParams *pqgParams;
    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;
    SECKeySizeChoiceInfo *choice = SECKeySizeChoiceList;
    nsIGeneratingKeypairInfoDialogs * dialogs;
    nsKeygenThread *KeygenRunnable = 0;
    nsCOMPtr<nsIKeygenThread> runnable;

    // Get the key size //
    while (choice->name) {
        if (aValue.Equals(choice->name)) {
            keysize = choice->size;
            break;
        }
        choice++;
    }
    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;
        pqgString = ToNewCString(aPqg);
        if (!pqgString) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            goto loser;
        }

        type = dsaKey;
        keyGenMechanism = CKM_DSA_KEY_PAIR_GEN;
        if (strcmp(pqgString, "null") == 0)
            goto loser;
        str = pqgString;
        do {
            end = strchr(str, ',');
            if (end != nsnull)
                *end = '\0';
            primeBits = pqg_prime_bits(str);
            if (choice->size == primeBits)
                goto found_match;
            str = end + 1;
        } while (end != nsnull);
        goto loser;
found_match:
        pqgParams = decode_pqg_params(str);
    } 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;
      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();
        if (KeygenRunnable) {
            NS_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 (pqgString) {
        nsMemory::Free(pqgString);
    }
    if (pkac.challenge.data) {
        nsMemory::Free(pkac.challenge.data);
    }
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsKeygenFormProcessor::GetSlot ( PRUint32  aMechanism,
PK11SlotInfo **  aSlot 
) [protected]

Definition at line 234 of file nsKeygenHandler.cpp.

{
  return GetSlotWithMechanism(aMechanism,m_ctx,aSlot);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 210 of file nsKeygenHandler.cpp.

{
  nsresult rv;
  nsAutoString str;

  if (SECKeySizeChoiceList[0].name != NULL)
    return NS_OK;

  // Get the key strings //
  nsCOMPtr<nsINSSComponent> nssComponent;
  nssComponent = do_GetService(kNSSComponentCID, &rv);
  if (NS_FAILED(rv))
    return rv;

  nssComponent->GetPIPNSSBundleString("HighGrade", str);
  SECKeySizeChoiceList[0].name = ToNewUnicode(str);

  nssComponent->GetPIPNSSBundleString("MediumGrade", str);
  SECKeySizeChoiceList[1].name = ToNewUnicode(str);

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_METHOD nsKeygenFormProcessor::ProcessValue ( nsIDOMHTMLElement aElement,
const nsAString &  aName,
nsAString &  aValue 
) [virtual]

Implements nsIFormProcessor.

Definition at line 634 of file nsKeygenHandler.cpp.

{ 
  nsresult rv = NS_OK;
  nsCOMPtr<nsIDOMHTMLSelectElement>selectElement;
  nsresult res = aElement->QueryInterface(kIDOMHTMLSelectElementIID, 
                                     getter_AddRefs(selectElement));
  if (NS_SUCCEEDED(res)) {
    nsAutoString keygenvalue;
    nsAutoString challengeValue;
    nsAutoString keyTypeValue;
    nsAutoString pqgValue;

    res = selectElement->GetAttribute(NS_LITERAL_STRING("_moz-type"), keygenvalue);
    if (NS_CONTENT_ATTR_HAS_VALUE == res && keygenvalue.EqualsLiteral("-mozilla-keygen")) {

      res = selectElement->GetAttribute(NS_LITERAL_STRING("pqg"), pqgValue);
      res = selectElement->GetAttribute(NS_LITERAL_STRING("keytype"), keyTypeValue);
      if (NS_FAILED(res) || keyTypeValue.IsEmpty()) {
        // If this field is not present, we default to rsa.
           keyTypeValue.AssignLiteral("rsa");
      }
      res = selectElement->GetAttribute(NS_LITERAL_STRING("challenge"), challengeValue);
      rv = GetPublicKey(aValue, challengeValue, keyTypeValue, 
                     aValue, pqgValue);
    }
  }

  return rv; 
} 

Here is the call graph for this function:

NS_METHOD nsKeygenFormProcessor::ProvideContent ( const nsAString &  aFormType,
nsVoidArray aContent,
nsAString &  aAttribute 
) [virtual]

Implements nsIFormProcessor.

Definition at line 666 of file nsKeygenHandler.cpp.

{ 
  if (Compare(aFormType, NS_LITERAL_STRING("SELECT"), 
    nsCaseInsensitiveStringComparator()) == 0) {
    for (SECKeySizeChoiceInfo* choice = SECKeySizeChoiceList; choice && choice->name; ++choice) {
      nsString *str = new nsString(choice->name);
      aContent.AppendElement(str);
    }
    aAttribute.AssignLiteral("-mozilla-keygen");
  }
  return NS_OK;
} 

Here is the call graph for this function:


Member Data Documentation

Definition at line 81 of file nsKeygenHandler.h.


The documentation for this class was generated from the following files: