Пример #1
0
static int  	
xmlSecNssKWAesOp(const xmlSecByte *key, xmlSecSize keySize,
		 const xmlSecByte *in, xmlSecSize inSize,
		 xmlSecByte *out, xmlSecSize outSize, int enc) {

    CK_MECHANISM_TYPE  cipherMech;
    PK11SlotInfo*      slot = NULL;
    PK11SymKey*        aeskey = NULL;
    SECItem*           SecParam = NULL;
    PK11Context*       EncContext = NULL;
    SECItem            keyItem;
    SECStatus          rv;
    int                result_len = -1;
    int                tmp1_outlen;
    unsigned int       tmp2_outlen;
    
    xmlSecAssert2(key != NULL, -1);
    xmlSecAssert2(keySize > 0, -1);
    xmlSecAssert2(in != NULL, -1);
    xmlSecAssert2(inSize > 0, -1);
    xmlSecAssert2(out != NULL, -1);
    xmlSecAssert2(outSize >= inSize + 8, -1);

    cipherMech = CKM_NETSCAPE_AES_KEY_WRAP;
    slot = PK11_GetBestSlot(cipherMech, NULL);
    if (slot == NULL) {
	xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
		    NULL,
		    "PK11_GetBestSlot",
		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
		    XMLSEC_ERRORS_NO_MESSAGE);
	goto done;
    }

    keyItem.data = (unsigned char *)key;
    keyItem.len = keySize;
    aeskey = PK11_ImportSymKey(slot, cipherMech, PK11_OriginUnwrap, 
		    	       enc ? CKA_ENCRYPT : CKA_DECRYPT, &keyItem, NULL);
    if (aeskey == NULL) {
	xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
		    NULL,
		    "PK11_ImportSymKey",
		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
		    XMLSEC_ERRORS_NO_MESSAGE);
	goto done;
    }

    SecParam = PK11_ParamFromIV(cipherMech, NULL);
    if (SecParam == NULL) {
	xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
		    NULL,
		    "PK11_ParamFromIV",
		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
		    XMLSEC_ERRORS_NO_MESSAGE);
	goto done;
    }

    EncContext = PK11_CreateContextBySymKey(cipherMech, 
		    			    enc ? CKA_ENCRYPT : CKA_DECRYPT, 
					    aeskey, SecParam);
    if (EncContext == NULL) {
	xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
		    NULL,
		    "PK11_CreateContextBySymKey",
		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
		    XMLSEC_ERRORS_NO_MESSAGE);
	goto done;
    }

    tmp1_outlen = tmp2_outlen = 0;
    rv = PK11_CipherOp(EncContext, out, &tmp1_outlen, outSize,
		       (unsigned char *)in, inSize);
    if (rv != SECSuccess) {
	xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
		    NULL,
		    "PK11_CipherOp",
		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
		    XMLSEC_ERRORS_NO_MESSAGE);
	goto done;
    }

    rv = PK11_DigestFinal(EncContext, out+tmp1_outlen, 
		    	  &tmp2_outlen, outSize-tmp1_outlen);
    if (rv != SECSuccess) {
	xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
		    NULL,
		    "PK11_DigestFinal",
		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
		    XMLSEC_ERRORS_NO_MESSAGE);
	goto done;
    }

    result_len = tmp1_outlen + tmp2_outlen;

done:
    if (slot) {
	PK11_FreeSlot(slot);
    }
    if (aeskey) {
	PK11_FreeSymKey(aeskey);
    }
    if (SecParam) {
	SECITEM_FreeItem(SecParam, PR_TRUE);
    }
    if (EncContext) {
	PK11_DestroyContext(EncContext, PR_TRUE);
    }

    return(result_len);
}
Пример #2
0
int main(int argc, char **argv)
{
  CK_MECHANISM_TYPE  hashMech;
  PK11SlotInfo*      slot = NULL;
  PK11SymKey*        SymKey = NULL;
  SECItem            SecParam;
  PK11Context*       HashContext = NULL;
  SECItem            keyItem;
  SECStatus          rv, rv1, rv2;
  unsigned char      buf1[1024], buf2[1024];
  char		     data[1024];
  int                i;
  unsigned int       tmp2_outlen;

  /* Initialize NSS
 *    * If your application code has already initialized NSS, you can skip it
 *       * here.
 *          * This code uses the simplest of the Init functions, which does not
 *             * require a NSS database to exist
 *                */
  rv = NSS_NoDB_Init(".");
  if (rv != SECSuccess)
  {
    fprintf(stderr, "NSS initialization failed (err %d)\n",
            PR_GetError());
    goto out;
  }

  /* choose mechanism: CKM_DES_CBC_PAD, CKM_DES3_ECB, CKM_DES3_CBC..... 
 *    * Note that some mechanisms (*_PAD) imply the padding is handled for you
 *       * by NSS. If you choose something else, then data padding is the
 *          * application's responsibility
 *             */
  hashMech = CKM_SHA_1_HMAC;
  slot = PK11_GetBestSlot(hashMech, NULL);
  /* slot = PK11_GetInternalKeySlot(); is a simpler alternative but in
 *    * theory, it *may not* return the optimal slot for the operation. For
 *       * DES ops, Internal slot is typically the best slot
 *          */
  if (slot == NULL)
  {
    fprintf(stderr, "Unable to find security device (err %d)\n",
            PR_GetError());
    goto out;
  }

  /* NSS passes blobs around as SECItems. These contain a pointer to
 *    * data and a length. Turn the raw key into a SECItem. */
  keyItem.type = siBuffer;
  keyItem.data = gKey;
  keyItem.len = sizeof(gKey);

  /* Turn the raw key into a key object. We use PK11_OriginUnwrap
 *    * to indicate the key was unwrapped - which is what should be done
 *       * normally anyway - using raw keys isn't a good idea */
  SymKey = PK11_ImportSymKey(slot, hashMech, PK11_OriginUnwrap, CKA_SIGN,
                             &keyItem, NULL);
  if (SymKey == NULL)
  {
    fprintf(stderr, "Failure to import key into NSS (err %d)\n",
            PR_GetError());
    goto out;
  }

  SecParam.type = siBuffer;
  SecParam.data = 0;
  SecParam.len = 0;

  /* sample data we'll hash */
  strcpy(data, "Hash me!");
  fprintf(stderr, "Clear Data: %s\n", data);

  /* ========================= START SECTION ============================= */
  /* If using the the same key and iv over and over, stuff before this     */
  /* section and after this section needs to be done only ONCE             */

  /* Create cipher context */
  HashContext = PK11_CreateContextBySymKey(hashMech, CKA_SIGN,
                                          SymKey, &SecParam);

  if (!HashContext) {
    fprintf(stderr, "no hash context today?\n");
    goto out;
  }

  if (PK11_DigestBegin(HashContext) != SECSuccess) {
    fprintf(stderr, "hash doesn't begin?\n");
    goto out;
  }

  rv1 = PK11_DigestOp(HashContext, (unsigned char *)data, strlen(data)+1);

  rv2 = PK11_DigestFinal(HashContext, buf2, &tmp2_outlen, SHA1_BLOCK_LENGTH);

  PK11_DestroyContext(HashContext, PR_TRUE);
  if (rv1 != SECSuccess || rv2 != SECSuccess)
    goto out;

  fprintf(stderr, "Hash Data: ");
  for (i=0; i<tmp2_outlen; i++)
    fprintf(stderr, "%02x ", buf2[i]);
  fprintf(stderr, "\n");

  /* =========================== END SECTION ============================= */

  /* ========================= START SECTION ============================= */
  /* If using the the same key and iv over and over, stuff before this     */
  /* section and after this section needs to be done only ONCE             */

  memset(buf1, 0, sizeof(buf1));
  memset(buf2, 0, sizeof(buf2));

  /* Create cipher context */
  HashContext = PK11_CreateContextBySymKey(hashMech, CKA_SIGN,
                                          SymKey, &SecParam);

  if (!HashContext) {
    fprintf(stderr, "no hash context today?\n");
    goto out;
  }

  if (PK11_DigestBegin(HashContext) != SECSuccess) {
    fprintf(stderr, "hash doesn't begin?\n");
    goto out;
  }

  rv1 = PK11_DigestOp(HashContext, (unsigned char *)data, 5);
  rv1 = PK11_DigestOp(HashContext, (unsigned char *)data+5, 4);

  rv2 = PK11_DigestFinal(HashContext, buf2, &tmp2_outlen, SHA1_BLOCK_LENGTH);

  PK11_DestroyContext(HashContext, PR_TRUE);
  if (rv1 != SECSuccess || rv2 != SECSuccess)
    goto out;

  fprintf(stderr, "Hash Data: ");
  for (i=0; i<tmp2_outlen; i++)
    fprintf(stderr, "%02x ", buf2[i]);
  fprintf(stderr, "\n");

  /* =========================== END SECTION ============================= */

 
out:
  if (SymKey)
    PK11_FreeSymKey(SymKey);

 return 0;

}
Пример #3
0
char *
crypto_decrypt (const char *cipher,
                int key_type,
                const guint8 *data,
                gsize data_len,
                const char *iv,
                const gsize iv_len,
                const char *key,
                const gsize key_len,
                gsize *out_len,
                GError **error)
{
	char *output = NULL;
	int decrypted_len = 0;
	CK_MECHANISM_TYPE cipher_mech;
	PK11SlotInfo *slot = NULL;
	SECItem key_item;
	PK11SymKey *sym_key = NULL;
	SECItem *sec_param = NULL;
	PK11Context *ctx = NULL;
	SECStatus s;
	gboolean success = FALSE;
	unsigned int pad_len = 0, extra = 0;
	guint32 i, real_iv_len = 0;

	if (!crypto_init (error))
		return NULL;

	if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) {
		cipher_mech = CKM_DES3_CBC_PAD;
		real_iv_len = 8;
	} else if (!strcmp (cipher, CIPHER_DES_CBC)) {
		cipher_mech = CKM_DES_CBC_PAD;
		real_iv_len = 8;
	} else if (!strcmp (cipher, CIPHER_AES_CBC)) {
		cipher_mech = CKM_AES_CBC_PAD;
		real_iv_len = 16;
	} else {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
		             _("Private key cipher '%s' was unknown."),
		             cipher);
		return NULL;
	}

	if (iv_len < real_iv_len) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_INVALID_DATA,
		             _("Invalid IV length (must be at least %d)."),
		             real_iv_len);
		return NULL;
	}

	output = g_malloc0 (data_len);

	slot = PK11_GetBestSlot (cipher_mech, NULL);
	if (!slot) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_FAILED,
		             _("Failed to initialize the decryption cipher slot."));
		goto out;
	}

	key_item.data = (unsigned char *) key;
	key_item.len = key_len;
	sym_key = PK11_ImportSymKey (slot, cipher_mech, PK11_OriginUnwrap, CKA_DECRYPT, &key_item, NULL);
	if (!sym_key) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
		             _("Failed to set symmetric key for decryption."));
		goto out;
	}

	key_item.data = (unsigned char *) iv;
	key_item.len = real_iv_len;
	sec_param = PK11_ParamFromIV (cipher_mech, &key_item);
	if (!sec_param) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
		             _("Failed to set IV for decryption."));
		goto out;
	}

	ctx = PK11_CreateContextBySymKey (cipher_mech, CKA_DECRYPT, sym_key, sec_param);
	if (!ctx) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
		             _("Failed to initialize the decryption context."));
		goto out;
	}

	s = PK11_CipherOp (ctx,
	                   (unsigned char *) output,
	                   &decrypted_len,
	                   data_len,
	                   data,
	                   data_len);
	if (s != SECSuccess) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
		             _("Failed to decrypt the private key: %d."),
		             PORT_GetError ());
		goto out;
	}

	if (decrypted_len > data_len) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
		             _("Failed to decrypt the private key: decrypted data too large."));
		goto out;
	}

	s = PK11_DigestFinal (ctx,
	                      (unsigned char *) (output + decrypted_len),
	                      &extra,
	                      data_len - decrypted_len);
	if (s != SECSuccess) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
		             _("Failed to finalize decryption of the private key: %d."),
		             PORT_GetError ());
		goto out;
	}
	decrypted_len += extra;
	pad_len = data_len - decrypted_len;

	/* Check if the padding at the end of the decrypted data is valid */
	if (pad_len == 0 || pad_len > real_iv_len) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
		             _("Failed to decrypt the private key: unexpected padding length."));
		goto out;
	}

	/* Validate tail padding; last byte is the padding size, and all pad bytes
	 * should contain the padding size.
	 */
	for (i = pad_len; i > 0; i--) {
		if (output[data_len - i] != pad_len) {
			g_set_error (error, NM_CRYPTO_ERROR,
			             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
			             _("Failed to decrypt the private key."));
			goto out;
		}
	}

	*out_len = decrypted_len;
	success = TRUE;

out:
	if (ctx)
		PK11_DestroyContext (ctx, PR_TRUE);
	if (sym_key)
		PK11_FreeSymKey (sym_key);
	if (sec_param)
		SECITEM_FreeItem (sec_param, PR_TRUE);
	if (slot)
		PK11_FreeSlot (slot);

	if (!success) {
		if (output) {
			/* Don't expose key material */
			memset (output, 0, data_len);
			g_free (output);
			output = NULL;
		}
	}
	return output;
}
Пример #4
0
/* encrypt a block (XMLSEC_NSS_AES_BLOCK_SIZE), in and out can overlap */
static void
xmlSecNssAesOp(PK11SymKey *aeskey, const xmlSecByte *in, xmlSecByte *out,
	       int enc) {

    CK_MECHANISM_TYPE  cipherMech;
    SECItem*           SecParam = NULL;
    PK11Context*       EncContext = NULL;
    SECStatus          rv;
    int                tmp1_outlen;
    unsigned int       tmp2_outlen;

    xmlSecAssert(in != NULL);
    xmlSecAssert(out != NULL);

    cipherMech = CKM_AES_ECB;
    SecParam = PK11_ParamFromIV(cipherMech, NULL);
    if (SecParam == NULL) {
	xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
		    NULL,
		    "PK11_ParamFromIV",
		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
		    XMLSEC_ERRORS_NO_MESSAGE);
	goto done;
    }

    EncContext = PK11_CreateContextBySymKey(cipherMech, 
		    			    enc ? CKA_ENCRYPT : CKA_DECRYPT, 
					    aeskey, SecParam);
    if (EncContext == NULL) {
	xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
		    NULL,
		    "PK11_CreateContextBySymKey",
		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
		    XMLSEC_ERRORS_NO_MESSAGE);
	goto done;
    }

    tmp1_outlen = tmp2_outlen = 0;
    rv = PK11_CipherOp(EncContext, out, &tmp1_outlen, 
		       XMLSEC_NSS_AES_BLOCK_SIZE, (unsigned char *)in, 
		       XMLSEC_NSS_AES_BLOCK_SIZE);
    if (rv != SECSuccess) {
	xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
		    NULL,
		    "PK11_CipherOp",
		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
		    XMLSEC_ERRORS_NO_MESSAGE);
	goto done;
    }

    rv = PK11_DigestFinal(EncContext, out+tmp1_outlen, 
		    	  &tmp2_outlen, XMLSEC_NSS_AES_BLOCK_SIZE-tmp1_outlen);
    if (rv != SECSuccess) {
	xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE,
		    NULL,
		    "PK11_DigestFinal",
		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
		    XMLSEC_ERRORS_NO_MESSAGE);
	goto done;
    }

done:
    if (SecParam) {
	SECITEM_FreeItem(SecParam, PR_TRUE);
    }
    if (EncContext) {
	PK11_DestroyContext(EncContext, PR_TRUE);
    }

}
Пример #5
0
size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len,
			const unsigned char *input, size_t input_len,
			const unsigned char *iv, unsigned char **res)
{
#define CIPHER_MECH CKM_DES3_CBC
#define MAX_OUTPUT_LEN 72

	int len1;
	unsigned int len2;

	PK11Context *ctx = NULL;
	PK11SlotInfo *slot = NULL;
	SECItem keyItem;
	SECItem ivItem;
	SECItem *secParam = NULL;
	PK11SymKey *symKey = NULL;

	size_t rc;
	SECStatus rv;

	if (!initialized) {
		ssl_init();
	}

	keyItem.data = (unsigned char *)key;
	keyItem.len = key_len;

	slot = PK11_GetBestSlot(CIPHER_MECH, NULL);
	if (slot == NULL) {
		fprintf(stderr, "PK11_GetBestSlot failed (err %d)\n",
			PR_GetError());
		rc = 0;
		goto out;
	}

	symKey =
	    PK11_ImportSymKey(slot, CIPHER_MECH, PK11_OriginUnwrap, CKA_ENCRYPT,
			      &keyItem, NULL);
	if (symKey == NULL) {
		fprintf(stderr, "PK11_ImportSymKey failed (err %d)\n",
			PR_GetError());
		rc = 0;
		goto out;
	}

	ivItem.data = (unsigned char *)iv;
	/* See msn_soap_passport_sso_handle_response in protocols/msn/soap.c */
	ivItem.len = 8;

	secParam = PK11_ParamFromIV(CIPHER_MECH, &ivItem);
	if (secParam == NULL) {
		fprintf(stderr, "PK11_ParamFromIV failed (err %d)\n",
			PR_GetError());
		rc = 0;
		goto out;
	}

	ctx =
	    PK11_CreateContextBySymKey(CIPHER_MECH, CKA_ENCRYPT, symKey,
				       secParam);
	if (ctx == NULL) {
		fprintf(stderr, "PK11_CreateContextBySymKey failed (err %d)\n",
			PR_GetError());
		rc = 0;
		goto out;
	}

	*res = g_new0(unsigned char, MAX_OUTPUT_LEN);

	rv = PK11_CipherOp(ctx, *res, &len1, MAX_OUTPUT_LEN,
			   (unsigned char *)input, input_len);
	if (rv != SECSuccess) {
		fprintf(stderr, "PK11_CipherOp failed (err %d)\n",
			PR_GetError());
		rc = 0;
		goto out;
	}

	assert(len1 <= MAX_OUTPUT_LEN);

	rv = PK11_DigestFinal(ctx, *res + len1, &len2,
			      (unsigned int)MAX_OUTPUT_LEN - len1);
	if (rv != SECSuccess) {
		fprintf(stderr, "PK11_DigestFinal failed (err %d)\n",
			PR_GetError());
		rc = 0;
		goto out;
	}

	rc = len1 + len2;

 out:
	if (ctx)
		PK11_DestroyContext(ctx, PR_TRUE);
	if (symKey)
		PK11_FreeSymKey(symKey);
	if (secParam)
		SECITEM_FreeItem(secParam, PR_TRUE);
	if (slot)
		PK11_FreeSlot(slot);

	return rc;
}
Пример #6
0
static int
xmlSecNssDigestExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
    xmlSecNssDigestCtxPtr ctx;
    xmlSecBufferPtr in, out;
    SECStatus rv;
    int ret;

    xmlSecAssert2(xmlSecNssDigestCheckId(transform), -1);
    xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
    xmlSecAssert2(transformCtx != NULL, -1);
    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssDigestSize), -1);

    ctx = xmlSecNssDigestGetCtx(transform);
    xmlSecAssert2(ctx != NULL, -1);
    xmlSecAssert2(ctx->digestCtx != NULL, -1);

    in = &(transform->inBuf);
    out = &(transform->outBuf);

    if(transform->status == xmlSecTransformStatusNone) {
        rv = PK11_DigestBegin(ctx->digestCtx);
        if(rv != SECSuccess) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                        "PK11_DigestBegin",
                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
                        "error code=%d", PORT_GetError());
            return(-1);
        }
        transform->status = xmlSecTransformStatusWorking;
    }

    if(transform->status == xmlSecTransformStatusWorking) {
        xmlSecSize inSize;

        inSize = xmlSecBufferGetSize(in);
        if(inSize > 0) {
            rv = PK11_DigestOp(ctx->digestCtx, xmlSecBufferGetData(in), inSize);
            if (rv != SECSuccess) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "PK11_DigestOp",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            "error code=%d", PORT_GetError());
                return(-1);
            }

            ret = xmlSecBufferRemoveHead(in, inSize);
            if(ret < 0) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "xmlSecBufferRemoveHead",
                            XMLSEC_ERRORS_R_XMLSEC_FAILED,
                            "size=%d", inSize);
                return(-1);
            }
        }
        if(last) {
            unsigned int dgstSize;

            rv = PK11_DigestFinal(ctx->digestCtx, ctx->dgst, &dgstSize, sizeof(ctx->dgst));
            if(rv != SECSuccess) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "PK11_DigestFinal",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            "error code=%d", PORT_GetError());
                return(-1);
            }
            xmlSecAssert2(dgstSize > 0, -1);
            ctx->dgstSize = XMLSEC_SIZE_BAD_CAST(dgstSize);

            if(transform->operation == xmlSecTransformOperationSign) {
                ret = xmlSecBufferAppend(out, ctx->dgst, ctx->dgstSize);
                if(ret < 0) {
                    xmlSecError(XMLSEC_ERRORS_HERE,
                                xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                                "xmlSecBufferAppend",
                                XMLSEC_ERRORS_R_XMLSEC_FAILED,
                                "size=%d", ctx->dgstSize);
                    return(-1);
                }
            }
            transform->status = xmlSecTransformStatusFinished;
        }
    } else if(transform->status == xmlSecTransformStatusFinished) {
        /* the only way we can get here is if there is no input */
        xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1);
    } else {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                    NULL,
                    XMLSEC_ERRORS_R_INVALID_STATUS,
                    "status=%d", transform->status);
        return(-1);
    }

    return(0);
}
Пример #7
0
PK11SymKey *PK11_Derive_lsw(PK11SymKey *base, CK_MECHANISM_TYPE mechanism,
			     SECItem *param, CK_MECHANISM_TYPE target,
			     CK_ATTRIBUTE_TYPE operation, int keysize)
{
	SECOidTag oid;
	PK11Context *ctx;
	unsigned char dkey[HMAC_BUFSIZE * 2];
	SECItem dkey_param;
	SECStatus status;
	unsigned int len = 0;
	CK_EXTRACT_PARAMS bs;
	chunk_t dkey_chunk;

	if ( (param == NULL) && (keysize == 0)) {
		switch (mechanism) {
		case CKM_SHA256_KEY_DERIVATION:
			oid = SEC_OID_SHA256;
			break;
		case CKM_SHA384_KEY_DERIVATION:
			oid = SEC_OID_SHA384;
			break;
		case CKM_SHA512_KEY_DERIVATION:
			oid = SEC_OID_SHA512;
			break;
		default:
			return PK11_Derive(base, mechanism, param, target,
					   operation, keysize);
		}

		ctx = PK11_CreateDigestContext(oid);
		PR_ASSERT(ctx != NULL);
		status = PK11_DigestBegin(ctx);
		PR_ASSERT(status == SECSuccess);
		status = PK11_DigestKey(ctx, base);
		PR_ASSERT(status == SECSuccess);
		PK11_DigestFinal(ctx, dkey, &len, sizeof dkey);
		PK11_DestroyContext(ctx, PR_TRUE);

		dkey_chunk.ptr = dkey;
		dkey_chunk.len = len;

		PK11SymKey *tkey1 = pk11_derive_wrapper_lsw(base,
							    CKM_CONCATENATE_DATA_AND_BASE, dkey_chunk, CKM_EXTRACT_KEY_FROM_KEY, CKA_DERIVE,
							    0);
		PR_ASSERT(tkey1 != NULL);

		bs = 0;
		dkey_param.data = (unsigned char*)&bs;
		dkey_param.len = sizeof(bs);
		PK11SymKey *tkey2 = PK11_Derive(tkey1,
						CKM_EXTRACT_KEY_FROM_KEY,
						&dkey_param, target, operation,
						len);
		PR_ASSERT(tkey2 != NULL);

		if (tkey1 != NULL)
			PK11_FreeSymKey(tkey1);

		return tkey2;

	} else {
		return PK11_Derive(base, mechanism, param, target, operation,
				   keysize);
	}

}
Пример #8
0
int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded,
                         char **password)
{
    SECStatus sret;
    int ret;
    TALLOC_CTX *tmp_ctx = NULL;
    struct crypto_mech_data *mech_props;
    struct sss_nss_crypto_ctx *cctx;

    int plainlen;
    unsigned int digestlen;
    unsigned char *obfbuf = NULL;
    size_t obflen;
    char *pwdbuf;

    /* for unmarshaling data */
    uint16_t meth;
    uint16_t ctsize;
    size_t p = 0;
    unsigned char *cryptotext;
    unsigned char *keybuf;
    unsigned char *ivbuf;
    unsigned char sentinel_check[OBF_BUFFER_SENTINEL_SIZE];

    tmp_ctx = talloc_new(mem_ctx);
    if (!tmp_ctx) {
        return ENOMEM;
    }

    /* initialize NSS if needed */
    ret = nspr_nss_init();
    if (ret != EOK) {
        ret = EIO;
        goto done;
    }

    /* Base64 decode the incoming buffer */
    obfbuf = sss_base64_decode(tmp_ctx, b64encoded, &obflen);
    if (!obfbuf) {
        ret = ENOMEM;
        goto done;
    }

    /* unpack obfuscation buffer */
    SAFEALIGN_COPY_UINT16_CHECK(&meth, obfbuf+p, obflen, &p);
    DEBUG(SSSDBG_TRACE_INTERNAL, "Read method: %d\n", meth);
    SAFEALIGN_COPY_UINT16_CHECK(&ctsize, obfbuf+p, obflen, &p);
    DEBUG(SSSDBG_TRACE_INTERNAL, "Read bufsize: %d\n", ctsize);

    mech_props = get_crypto_mech_data(meth);
    if (mech_props == NULL) {
        ret = EINVAL;
        goto done;
    }

    /* check that we got sane mechanism properties and cryptotext size */
    memcpy(sentinel_check,
           obfbuf + p + mech_props->keylen + mech_props->bsize + ctsize,
           OBF_BUFFER_SENTINEL_SIZE);
    if (memcmp(sentinel_check, OBF_BUFFER_SENTINEL, OBF_BUFFER_SENTINEL_SIZE) != 0) {
        DEBUG(SSSDBG_FATAL_FAILURE,
              "Obfuscation buffer seems corrupt, aborting\n");
        ret = EFAULT;
        goto done;
    }

    /* copy out key, ivbuf and cryptotext */
    keybuf = talloc_array(tmp_ctx, unsigned char, mech_props->keylen);
    if (keybuf == NULL) {
        ret = ENOMEM;
        goto done;
    }
    safealign_memcpy(keybuf, obfbuf+p, mech_props->keylen, &p);

    ivbuf = talloc_array(tmp_ctx, unsigned char, mech_props->bsize);
    if (ivbuf == NULL) {
        ret = ENOMEM;
        goto done;
    }
    safealign_memcpy(ivbuf, obfbuf+p, mech_props->bsize, &p);

    cryptotext = talloc_array(tmp_ctx, unsigned char, ctsize);
    if (cryptotext == NULL) {
        ret = ENOMEM;
        goto done;
    }
    safealign_memcpy(cryptotext, obfbuf+p, ctsize, &p);

    ret = nss_ctx_init(tmp_ctx, mech_props, &cctx);
    if (ret) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Cannot initialize NSS context\n");
        goto done;
    }

    cctx->iv = talloc_zero(cctx, SECItem);
    cctx->key = talloc_zero(cctx, SECItem);
    if (!cctx->iv || !cctx->key) {
        ret = ENOMEM;
        goto done;
    }

    MAKE_SECITEM(ivbuf, mech_props->bsize, cctx->iv);
    MAKE_SECITEM(keybuf, mech_props->keylen, cctx->key);

    ret = nss_encrypt_decrypt_init(mech_props, false, cctx);
    if (ret) {
        goto done;
    }

    pwdbuf = talloc_array(tmp_ctx, char, ctsize);
    if (!pwdbuf) {
        ret = ENOMEM;
        goto done;
    }

    sret = PK11_CipherOp(cctx->ectx, (unsigned char *) pwdbuf, &plainlen, ctsize,
                         cryptotext, ctsize);
    if (sret != SECSuccess) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Cannot execute the encryption operation (err %d)\n",
                   PR_GetError());
        ret = EIO;
        goto done;
    }

    sret = PK11_DigestFinal(cctx->ectx, (unsigned char *) pwdbuf+plainlen, &digestlen,
                            ctsize - plainlen);
    if (sret != SECSuccess) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Cannot execute the encryption operation (err %d)\n",
                   PR_GetError());
        ret = EIO;
        goto done;
    }

    *password = talloc_move(mem_ctx, &pwdbuf);
    ret = EOK;
done:
    talloc_free(tmp_ctx);
    nspr_nss_cleanup();
    return ret;
}
Пример #9
0
int
generate_digest(pesign_context *ctx, Pe *pe)
{
	void *hash_base;
	size_t hash_size;
	struct pe32_opt_hdr *pe32opthdr = NULL;
	struct pe32plus_opt_hdr *pe64opthdr = NULL;
	PK11Context *pk11ctx;
	unsigned long hashed_bytes = 0;
	int rc = -1;

	if (!pe) {
		fprintf(stderr, "pesign: no output pe ready\n");
		exit(1);
	}

	struct pe_hdr pehdr;
	if (pe_getpehdr(pe, &pehdr) == NULL) {
		fprintf(stderr, "pesign: invalid output file header\n");
		exit(1);
	}

	void *map = NULL;
	size_t map_size = 0;

	/* 1. Load the image header into memory - should be done
	 * 2. Initialize SHA hash context. */
	map = pe_rawfile(pe, &map_size);
	if (!map) {
		fprintf(stderr, "pesign: could not get raw output file address\n");
		exit(1);
	}

	pk11ctx = PK11_CreateDigestContext(ctx->cms_ctx.digest_oid_tag);
	if (!pk11ctx) {
		fprintf(stderr, "pesign: could not initialize digest\n");
		exit(1);
	}
	PK11_DigestBegin(pk11ctx);

	/* 3. Calculate the distance from the base of the image header to the
	 * image checksum.
	 * 4. Hash the image header from start to the beginning of the
	 * checksum. */
	hash_base = map;
	switch (pe_kind(pe)) {
	case PE_K_PE_EXE: {
		void *opthdr = pe_getopthdr(pe);
		pe32opthdr = opthdr;
		hash_size = (uintptr_t)&pe32opthdr->csum - (uintptr_t)hash_base;
		break;
	}
	case PE_K_PE64_EXE: {
		void *opthdr = pe_getopthdr(pe);
		pe64opthdr = opthdr;
		hash_size = (uintptr_t)&pe64opthdr->csum - (uintptr_t)hash_base;
		break;
	}
	default:
		goto error;
	}
	PK11_DigestOp(pk11ctx, hash_base, hash_size);

	/* 5. Skip over the image checksum
	 * 6. Get the address of the beginning of the cert dir entry
	 * 7. Hash from the end of the csum to the start of the cert dirent. */
	hash_base += hash_size;
	hash_base += pe32opthdr ? sizeof(pe32opthdr->csum)
				: sizeof(pe64opthdr->csum);
	data_directory *dd;

	rc = pe_getdatadir(pe, &dd);
	if (rc < 0 || !dd)
		goto error;

	hash_size = (uintptr_t)&dd->certs - (uintptr_t)hash_base;
	PK11_DigestOp(pk11ctx, hash_base, hash_size);

	/* 8. Skip over the crt dir
	 * 9. Hash everything up to the end of the image header. */
	hash_base = &dd->base_relocations;
	hash_size = (pe32opthdr ? pe32opthdr->header_size
				: pe64opthdr->header_size) -
		((uintptr_t)&dd->base_relocations - (uintptr_t)map);
	PK11_DigestOp(pk11ctx, hash_base, hash_size);

	/* 10. Set SUM_OF_BYTES_HASHED to the size of the header. */
	hashed_bytes = pe32opthdr ? pe32opthdr->header_size
				: pe64opthdr->header_size;

	struct section_header *shdrs = calloc(pehdr.sections, sizeof (*shdrs));
	if (!shdrs)
		goto error;
	Pe_Scn *scn = NULL;
	for (int i = 0; i < pehdr.sections; i++) {
		scn = pe_nextscn(pe, scn);
		if (scn == NULL)
			break;
		pe_getshdr(scn, &shdrs[i]);
	}
	sort_shdrs(shdrs, pehdr.sections - 1);

	for (int i = 0; i < pehdr.sections; i++) {
		hash_base = (void *)((uintptr_t)map + shdrs[i].data_addr);
		hash_size = shdrs[i].raw_data_size;
		PK11_DigestOp(pk11ctx, hash_base, hash_size);

		hashed_bytes += hash_size;
	}

	if (map_size > hashed_bytes) {
		hash_base = (void *)((uintptr_t)map + hashed_bytes);
		hash_size = map_size - dd->certs.size - hashed_bytes;
		PK11_DigestOp(pk11ctx, hash_base, hash_size);
	}

	SECItem *digest = PORT_ArenaZAlloc(ctx->cms_ctx.arena,
					sizeof (SECItem));
	if (!digest)
		goto error_shdrs;

	digest->type = siBuffer;
	digest->data = PORT_ArenaZAlloc(ctx->cms_ctx.arena,
						ctx->cms_ctx.digest_size);
	digest->len = ctx->cms_ctx.digest_size;
	if (!digest->data)
		goto error_digest;

	PK11_DigestFinal(pk11ctx, digest->data, &digest->len,
						ctx->cms_ctx.digest_size);
	ctx->cms_ctx.pe_digest = digest;

	if (shdrs)
		free(shdrs);
	PK11_DestroyContext(pk11ctx, PR_TRUE);

	return 0;

error_digest:
	PORT_Free(digest->data);
error_shdrs:
	if (shdrs)
		free(shdrs);
error:
	PK11_DestroyContext(pk11ctx, PR_TRUE);
	fprintf(stderr, "pesign: could not digest file.\n");
	exit(1);
}
Пример #10
0
TPS_PUBLIC PRStatus Util::ComputeMAC(PK11SymKey *key, Buffer &x_input, 
		const Buffer &icv, Buffer &output)
{
    PRStatus rv = PR_SUCCESS;
    PK11Context *context = NULL;
//    NetkeyICV temp;
    unsigned char result[8];
    int i;
    SECStatus s;
    int len;
#ifdef USE_DESMAC
    CK_ULONG macLen = sizeof result;
    SECItem params = { siBuffer, (unsigned char *)&macLen, sizeof macLen };
#endif
    static SECItem noParams = { siBuffer, 0, 0 };
    static unsigned char macPad[] = {
        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    BYTE *input = (BYTE *) x_input;	
    int inputLen = x_input.size();

#ifdef USE_DESMAC
    context = PK11_CreateContextBySymKey(CKM_DES3_MAC_GENERAL, CKA_SIGN,
                                key, &params);
    if (!context) { rv = PR_FAILURE; goto done; }

    s = PK11_DigestBegin(context);
    if (s != SECSuccess) { rv = PR_FAILURE; goto done; }

    s = PK11_DigestOp(context, icv, 8);
    if (s != SECSuccess) { rv = PR_FAILURE; goto done; }

    while(inputLen >= 8)
    {
        s = PK11_DigestOp(context, input, 8);
        if (s != SECSuccess) { rv = PR_FAILURE; goto done; }

        input += 8;
        inputLen -= 8;
    }

    for (i = 0;i < inputLen;i++)
    {
        result[i] = input[i];
    }

    input = macPad;
    for(;i < 8;i++)
    {
        result[i] = *input++;
    }

    s = PK11_DigestOp(context, result, sizeof result);
    if (s != SECSuccess) { rv = PR_FAILURE; goto done; }

    s = PK11_DigestFinal(context, output, (unsigned int *)&len, sizeof output);
    if (1 != SECSuccess) { rv = PR_FAILURE; goto done; }

#else

    context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, key, &noParams);
    if (!context) { rv = PR_FAILURE; goto done; }

    memcpy(result, icv, sizeof result);

    /* Process whole blocks */
    while(inputLen >= 8)
    {
        for(i = 0;i < 8;i++)
        {
            result[i] ^= input[i];
        }

        s = PK11_CipherOp(context, result, &len, sizeof result, result, sizeof result);
        if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
        if (len != sizeof result) /* assert? */
        {
            //PR_SetError(PR_UNKNOWN_ERROR, 0);
            rv = PR_FAILURE;
            goto done;
        }

        input += 8;
        inputLen -= 8;
    }

    /*
     * Fold in remaining data (if any)
     * Set i to number of bytes processed
     */
    for(i = 0;i < inputLen;i++)
    {
        result[i] ^= input[i];
    }

    /*
     * Fill remainder of last block. There
     * will be at least one byte handled here.
     */
    input = macPad;
    while(i < 8)
    {
        result[i] ^= *input++;
        i++;
    }

    s = PK11_CipherOp(context, result, &len, sizeof result, result, sizeof result);
    if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
    if (len != sizeof result)
    {
        //PR_SetError(PR_UNKNOWN_ERROR, 0);
        rv = PR_FAILURE;
        goto done;
    }

    output.replace(0, result, sizeof result);
#endif

done:
    if( context != NULL )
    {
        PK11_Finalize( context );
        PK11_DestroyContext( context, PR_TRUE );
        context = NULL;
    }
    memset(result, 0, sizeof result);

    return rv;
} /* ComputeMAC */
Пример #11
0
int main (int argc, char *argv[])
{
	cpg_handle_t handle;
	cs_error_t result;
	int i = 0;
	int j;
	struct my_msg msg;
	struct iovec iov[2];
	const char *options = "i:";
	int iter = 1000;
	int opt;
	int run_forever = 1;
	unsigned int sha1_len;

	while ((opt = getopt(argc, argv, options)) != -1) {
		switch (opt) {
		case 'i':
			run_forever = 0;
			iter = atoi(optarg);
			break;
		}
	}

	result = cpg_initialize (&handle, &callbacks);
	if (result != CS_OK) {
		printf ("Couldn't initialize CPG service %d\n", result);
		exit (0);
	}

	if (NSS_NoDB_Init(".") != SECSuccess) {
		printf ("Couldn't initialize nss\n");
		exit (0);
	}

	if ((sha1_context = PK11_CreateDigestContext(SEC_OID_SHA1)) == NULL) {
		printf ("Couldn't initialize nss\n");
		exit (0);
	}

        result = cpg_join (handle, &group_name);
        if (result != CS_OK) {
                printf ("cpg_join failed with result %d\n", result);
                exit (1);
        }

	iov[0].iov_base = (void *)&msg;
	iov[0].iov_len = sizeof (struct my_msg);
	iov[1].iov_base = (void *)buffer;

	/*
	 * Demonstrate cpg_mcast_joined
	 */
	i = 0;
	do {
		msg.msg_size = 100 + rand() % 100000;
		iov[1].iov_len = msg.msg_size;
		for (j = 0; j < msg.msg_size; j++) {
			buffer[j] = j;
		}
		sprintf ((char *)buffer,
			"cpg_mcast_joined: This is message %12d", i);

		PK11_DigestBegin(sha1_context);
		PK11_DigestOp(sha1_context, buffer, msg.msg_size);
		PK11_DigestFinal(sha1_context, msg.sha1, &sha1_len, sizeof(msg.sha1));
try_again_one:
		result = cpg_mcast_joined (handle, CPG_TYPE_AGREED,
			iov, 2);
		if (result == CS_ERR_TRY_AGAIN) {
			goto try_again_one;
		}
		result = cpg_dispatch (handle, CS_DISPATCH_ALL);
		i++;
	} while (run_forever || i < iter);

	PK11_DestroyContext(sha1_context, PR_TRUE);

	cpg_finalize (handle);

	return (0);
}
Пример #12
0
static int calculate_nss_hash(
	knet_handle_t knet_h,
	const unsigned char *buf,
	const size_t buf_len,
	unsigned char *hash)
{
	struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
	PK11Context*	hash_context = NULL;
	SECItem		hash_param;
	unsigned int	hash_tmp_outlen = 0;
	int		err = -1;

	/* Now do the digest */
	hash_param.type = siBuffer;
	hash_param.data = 0;
	hash_param.len = 0;

	hash_context = PK11_CreateContextBySymKey(hash_to_nss[instance->crypto_hash_type],
						 CKA_SIGN,
						 instance->nss_sym_key_sign,
						 &hash_param);

	if (!hash_context) {
		log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_CreateContext failed (hash) hash_type=%d (err %d)",
			   (int)hash_to_nss[instance->crypto_hash_type],
			   PR_GetError());
		goto out;
	}

	if (PK11_DigestBegin(hash_context) != SECSuccess) {
		log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestBegin failed (hash) hash_type=%d (err %d)",
			   (int)hash_to_nss[instance->crypto_hash_type],
			   PR_GetError());
		goto out;
	}

	if (PK11_DigestOp(hash_context,
			  buf,
			  buf_len) != SECSuccess) {
		log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestOp failed (hash) hash_type=%d (err %d)",
			   (int)hash_to_nss[instance->crypto_hash_type],
			   PR_GetError());
		goto out;
	}

	if (PK11_DigestFinal(hash_context,
			     hash,
			     &hash_tmp_outlen,
			     hash_len[instance->crypto_hash_type]) != SECSuccess) {
		log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestFinale failed (hash) hash_type=%d (err %d)",
			   (int)hash_to_nss[instance->crypto_hash_type],
			   PR_GetError());
		goto out;
	}

	err = 0;

out:
	if (hash_context) {
		PK11_DestroyContext(hash_context, PR_TRUE);
	}

	return err;
}
Пример #13
0
static int encrypt_nss(
	knet_handle_t knet_h,
	const struct iovec *iov,
	int iovcnt,
	unsigned char *buf_out,
	ssize_t *buf_out_len)
{
	struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
	PK11Context*	crypt_context = NULL;
	SECItem		crypt_param;
	SECItem		*nss_sec_param = NULL;
	int		tmp_outlen = 0, tmp1_outlen = 0;
	unsigned int	tmp2_outlen = 0;
	unsigned char	*salt = buf_out;
	unsigned char	*data = buf_out + SALT_SIZE;
	int		err = -1;
	int		i;

	if (PK11_GenerateRandom (salt, SALT_SIZE) != SECSuccess) {
		log_err(knet_h, KNET_SUB_NSSCRYPTO, "Failure to generate a random number %d",
			   PR_GetError());
		goto out;
	}

	crypt_param.type = siBuffer;
	crypt_param.data = salt;
	crypt_param.len = SALT_SIZE;

	nss_sec_param = PK11_ParamFromIV (cipher_to_nss[instance->crypto_cipher_type],
					  &crypt_param);
	if (nss_sec_param == NULL) {
		log_err(knet_h, KNET_SUB_NSSCRYPTO, "Failure to set up PKCS11 param (err %d)",
			   PR_GetError());
		goto out;
	}

	/*
	 * Create cipher context for encryption
	 */
	crypt_context = PK11_CreateContextBySymKey (cipher_to_nss[instance->crypto_cipher_type],
						    CKA_ENCRYPT,
						    instance->nss_sym_key,
						    nss_sec_param);
	if (!crypt_context) {
		log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_CreateContext failed (encrypt) crypt_type=%d (err %d)",
			   (int)cipher_to_nss[instance->crypto_cipher_type],
			   PR_GetError());
		goto out;
	}

	for (i=0; i<iovcnt; i++) {
		if (PK11_CipherOp(crypt_context, data,
				  &tmp_outlen,
				  KNET_DATABUFSIZE_CRYPT,
				  (unsigned char *)iov[i].iov_base, iov[i].iov_len) != SECSuccess) {
			log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_CipherOp failed (encrypt) crypt_type=%d (err %d)",
				   (int)cipher_to_nss[instance->crypto_cipher_type],
				   PR_GetError());
			goto out;
		}
		tmp1_outlen = tmp1_outlen + tmp_outlen;
	}

	if (PK11_DigestFinal(crypt_context, data + tmp1_outlen,
			     &tmp2_outlen, KNET_DATABUFSIZE_CRYPT - tmp1_outlen) != SECSuccess) {
		log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestFinal failed (encrypt) crypt_type=%d (err %d)",
			   (int)cipher_to_nss[instance->crypto_cipher_type],
			   PR_GetError());
		goto out;

	}

	*buf_out_len = tmp1_outlen + tmp2_outlen + SALT_SIZE;

	err = 0;

out:
	if (crypt_context) {
		PK11_DestroyContext(crypt_context, PR_TRUE);
	}
	if (nss_sec_param) {
		SECITEM_FreeItem(nss_sec_param, PR_TRUE);
	}
	return err;
}
Пример #14
0
static void send_some_more_messages_zcb (void)
{
	msg_t *my_msg;
	int i;
	int send_now;
	size_t payload_size;
	size_t total_size;
	unsigned int sha1_len;
	cs_error_t res;
	cpg_flow_control_state_t fc_state;
	void *zcb_buffer;

	if (cpg_fd < 0)
		return;

	send_now = my_msgs_to_send;
	payload_size = (rand() % 100000);
	total_size = payload_size + sizeof (msg_t);
	cpg_zcb_alloc (cpg_handle, total_size, &zcb_buffer);

	my_msg = (msg_t*)zcb_buffer;

	qb_log(LOG_DEBUG, "send_now:%d", send_now);
	my_msg->pid = my_pid;
	my_msg->nodeid = my_nodeid;
	my_msg->size = sizeof (msg_t) + payload_size;
	my_msg->seq = my_msgs_sent;
	for (i = 0; i < payload_size; i++) {
		my_msg->payload[i] = i;
	}
	PK11_DigestBegin(sha1_context);
	PK11_DigestOp(sha1_context,  my_msg->payload, payload_size);
	PK11_DigestFinal(sha1_context, my_msg->sha1, &sha1_len, sizeof(my_msg->sha1));

	for (i = 0; i < send_now; i++) {

		res = cpg_flow_control_state_get (cpg_handle, &fc_state);
		if (res == CS_OK && fc_state == CPG_FLOW_CONTROL_ENABLED) {
			/* lets do this later */
			send_some_more_messages_later ();
			qb_log (LOG_INFO, "flow control enabled.");
			goto free_buffer;
		}

		res = cpg_zcb_mcast_joined (cpg_handle, CPG_TYPE_AGREED, zcb_buffer, total_size);
		if (res == CS_ERR_TRY_AGAIN) {
			/* lets do this later */
			send_some_more_messages_later ();
			goto free_buffer;
		} else if (res != CS_OK) {
			qb_log (LOG_ERR, "cpg_mcast_joined error:%d, exiting.",
				res);
			exit (-2);
		}

		my_msgs_sent++;
		my_msgs_to_send--;
	}
free_buffer:
	cpg_zcb_free (cpg_handle, zcb_buffer);
}
Пример #15
0
static gboolean
purple_aes_cipher_nss_crypt(const guchar *input, guchar *output, size_t len,
	guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size,
	CK_ATTRIBUTE_TYPE operation)
{
	PurpleAESCipherNSSContext context;
	CK_MECHANISM_TYPE cipher_mech = CKM_AES_CBC;
	SECItem key_item, iv_item;
	SECStatus ret;
	int outlen = 0;
	unsigned int outlen_tmp = 0;

	memset(&context, 0, sizeof(PurpleAESCipherNSSContext));

	if (NSS_NoDB_Init(NULL) != SECSuccess) {
		purple_debug_error("cipher-aes",
			"NSS_NoDB_Init failed: %d\n", PR_GetError());
		return FALSE;
	}

	context.slot = PK11_GetBestSlot(cipher_mech, NULL);
	if (context.slot == NULL) {
		purple_debug_error("cipher-aes",
			"PK11_GetBestSlot failed: %d\n", PR_GetError());
		return FALSE;
	}

	key_item.type = siBuffer;
	key_item.data = key;
	key_item.len = key_size;
	context.sym_key = PK11_ImportSymKey(context.slot, cipher_mech,
		PK11_OriginUnwrap, CKA_ENCRYPT, &key_item, NULL);
	if (context.sym_key == NULL) {
		purple_debug_error("cipher-aes",
			"PK11_ImportSymKey failed: %d\n", PR_GetError());
		purple_aes_cipher_nss_cleanup(&context);
		return FALSE;
	}

	iv_item.type = siBuffer;
	iv_item.data = iv;
	iv_item.len = PURPLE_AES_BLOCK_SIZE;
	context.sec_param = PK11_ParamFromIV(cipher_mech, &iv_item);
	if (context.sec_param == NULL) {
		purple_debug_error("cipher-aes",
			"PK11_ParamFromIV failed: %d\n", PR_GetError());
		purple_aes_cipher_nss_cleanup(&context);
		return FALSE;
	}

	context.enc_context = PK11_CreateContextBySymKey(cipher_mech, operation,
		context.sym_key, context.sec_param);
	if (context.enc_context == NULL) {
		purple_debug_error("cipher-aes",
			"PK11_CreateContextBySymKey failed: %d\n",
				PR_GetError());
		purple_aes_cipher_nss_cleanup(&context);
		return FALSE;
	}

	ret = PK11_CipherOp(context.enc_context, output, &outlen, len,
			(guchar *)input, len);
	if (ret != SECSuccess) {
		purple_debug_error("cipher-aes",
			"PK11_CipherOp failed: %d\n", PR_GetError());
		purple_aes_cipher_nss_cleanup(&context);
		return FALSE;
	}

	ret = PK11_DigestFinal(context.enc_context, output + outlen, &outlen_tmp,
		len - outlen);
	if (ret != SECSuccess) {
		purple_debug_error("cipher-aes",
			"PK11_DigestFinal failed: %d\n", PR_GetError());
		purple_aes_cipher_nss_cleanup(&context);
		return FALSE;
	}

	purple_aes_cipher_nss_cleanup(&context);

	outlen += outlen_tmp;
	if (outlen != (int)len) {
		purple_debug_error("cipher-aes",
			"resulting length doesn't match: %d (expected: %lu)\n",
			outlen, len);
		return FALSE;
	}

	return TRUE;
}
Пример #16
0
static void send_some_more_messages_normal (void)
{
	msg_t my_msg;
	struct iovec iov[2];
	int i;
	int send_now;
	size_t payload_size;
	cs_error_t res;
	cpg_flow_control_state_t fc_state;
	int retries = 0;
	time_t before;
	unsigned int sha1_len;

	if (cpg_fd < 0)
		return;

	send_now = my_msgs_to_send;

	qb_log (LOG_TRACE, "send_now:%d", send_now);

	my_msg.pid = my_pid;
	my_msg.nodeid = my_nodeid;
	payload_size = (rand() % 10000);
	my_msg.size = sizeof (msg_t) + payload_size;
	my_msg.seq = my_msgs_sent;
	for (i = 0; i < payload_size; i++) {
		buffer[i] = i;
	}
	PK11_DigestBegin(sha1_context);
	PK11_DigestOp(sha1_context,  buffer, payload_size);
	PK11_DigestFinal(sha1_context, my_msg.sha1, &sha1_len, sizeof(my_msg.sha1));

	iov[0].iov_len = sizeof (msg_t);
	iov[0].iov_base = &my_msg;
	iov[1].iov_len = payload_size;
	iov[1].iov_base = buffer;

	for (i = 0; i < send_now; i++) {
		if (in_cnchg && pcmk_test) {
			retries = 0;
			before = time(NULL);
			cs_repeat(retries, 30, res = cpg_mcast_joined(cpg_handle, CPG_TYPE_AGREED, iov, 2));
			if (retries > 20) {
				qb_log (LOG_ERR, "cs_repeat: blocked for :%lu secs.",
					(unsigned long)(time(NULL) - before));
			}
			if (res != CS_OK) {
				qb_log (LOG_ERR, "cpg_mcast_joined error:%d.",
					res);
				return;
			}
		} else {
			res = cpg_flow_control_state_get (cpg_handle, &fc_state);
			if (res == CS_OK && fc_state == CPG_FLOW_CONTROL_ENABLED) {
				/* lets do this later */
				send_some_more_messages_later ();
				qb_log (LOG_INFO, "flow control enabled.");
				return;
			}

			res = cpg_mcast_joined (cpg_handle, CPG_TYPE_AGREED, iov, 2);
			if (res == CS_ERR_TRY_AGAIN) {
				/* lets do this later */
				send_some_more_messages_later ();
				if (i > 0) {
					qb_log (LOG_INFO, "TRY_AGAIN %d to send.",
						my_msgs_to_send);
				}
				return;
			} else if (res != CS_OK) {
				qb_log (LOG_ERR, "cpg_mcast_joined error:%d, exiting.",
					res);
				exit (-2);
			}
		}
		my_msgs_sent++;
		my_msg.seq = my_msgs_sent;
		my_msgs_to_send--;
	}
	qb_log (LOG_TRACE, "sent %d; to send %d.",
		my_msgs_sent, my_msgs_to_send);
}
Пример #17
0
int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen,
                         enum obfmethod meth, char **obfpwd)
{
    SECStatus sret;
    int ret;
    TALLOC_CTX *tmp_ctx = NULL;
    struct crypto_mech_data *mech_props;
    struct sss_nss_crypto_ctx *cctx;

    unsigned char *plaintext;

    unsigned char *cryptotext;
    int ct_maxsize;
    int ctlen;
    unsigned int digestlen;
    int result_len;

    unsigned char *obfbuf;
    size_t obufsize = 0;
    size_t p = 0;

    tmp_ctx = talloc_new(mem_ctx);
    if (!tmp_ctx) {
        return ENOMEM;
    }

    /* initialize NSS if needed */
    ret = nspr_nss_init();
    if (ret != EOK) {
        ret = EIO;
        goto done;
    }

    mech_props = get_crypto_mech_data(meth);
    if (mech_props == NULL) {
        ret = EINVAL;
        goto done;
    }

    ret = nss_ctx_init(tmp_ctx, mech_props, &cctx);
    if (ret) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Cannot initialize NSS context\n");
        goto done;
    }

    /* generate random encryption and IV key */
    ret = generate_random_key(cctx, cctx->slot, mech_props, &cctx->key);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Could not generate encryption key\n");
        goto done;
    }

    ret = generate_random_key(cctx, cctx->slot, mech_props, &cctx->iv);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Could not generate initialization vector\n");
        goto done;
    }

    ret = nss_encrypt_decrypt_init(mech_props, true, cctx);
    if (ret) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Cannot initialize NSS context properties\n");
        goto done;
    }

    plaintext = (unsigned char *) talloc_strndup(tmp_ctx, password, plen);
    if (!plaintext) {
        ret = ENOMEM;
        goto done;
    }

    /* cryptotext buffer must be at least len(plaintext)+blocksize */
    ct_maxsize = plen + (mech_props->bsize);
    cryptotext = talloc_array(tmp_ctx, unsigned char, ct_maxsize);
    if (!cryptotext) {
        ret = ENOMEM;
        goto done;
    }

    /* sample data we'll encrypt and decrypt */
    sret = PK11_CipherOp(cctx->ectx, cryptotext, &ctlen, ct_maxsize,
                         plaintext, plen);
    if (sret != SECSuccess) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Cannot execute the encryption operation (err %d)\n",
                   PR_GetError());
        ret = EIO;
        goto done;
    }

    sret = PK11_DigestFinal(cctx->ectx, cryptotext+ctlen, &digestlen,
                            ct_maxsize-ctlen);
    if (sret != SECSuccess) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Cannot execute the digest operation (err %d)\n",
                    PR_GetError());
        ret = EIO;
        goto done;
    }
    result_len = ctlen + digestlen;
    if (result_len < 0 || result_len > UINT16_MAX) {
        ret = ERANGE;
        goto done;
    }

    /* Pack the obfuscation buffer */
    /* The buffer consists of:
     * uint16_t      the type of the cipher
     * uint16_t      length of the cryptotext in bytes (clen)
     * uint8_t[klen] key
     * uint8_t[blen] IV
     * uint8_t[clen] cryptotext
     * 4 bytes of "sentinel" denoting end of the buffer
     */
    obufsize = sizeof(uint16_t) + sizeof(uint16_t) +
               mech_props->keylen + mech_props->bsize +
               result_len + OBF_BUFFER_SENTINEL_SIZE;
    obfbuf = talloc_array(tmp_ctx, unsigned char, obufsize);
    if (!obfbuf) {
        ret = ENOMEM;
        goto done;
    }

    DEBUG(SSSDBG_TRACE_INTERNAL, "Writing method: %d\n", meth);
    SAFEALIGN_SET_UINT16(&obfbuf[p], meth, &p);
    DEBUG(SSSDBG_TRACE_INTERNAL, "Writing bufsize: %d\n", result_len);
    SAFEALIGN_SET_UINT16(&obfbuf[p], result_len, &p);
    safealign_memcpy(&obfbuf[p], cctx->key->data, mech_props->keylen, &p);
    safealign_memcpy(&obfbuf[p], cctx->iv->data, mech_props->bsize, &p);
    safealign_memcpy(&obfbuf[p], cryptotext, result_len, &p);
    safealign_memcpy(&obfbuf[p], OBF_BUFFER_SENTINEL,
                     OBF_BUFFER_SENTINEL_SIZE, &p);

    /* Base64 encode the resulting buffer */
    *obfpwd = sss_base64_encode(mem_ctx, obfbuf, obufsize);
    if (*obfpwd == NULL) {
        ret = ENOMEM;
        goto done;
    }

    ret = EOK;
done:
    talloc_free(tmp_ctx);
    nspr_nss_cleanup();
    return ret;
}