// -----------------------------------------------------------------------------
// RSIPSecChallengeResolver::CreateChallengeL
// If qop exists, but has unknown value, ignore the challenge.
// -----------------------------------------------------------------------------
//
void
RSIPSecChallengeResolver::CreateChallengeL( CSIPAuthenticateHeaderBase& aHeader,
											CSIPSecDigest::TChallengeType aType,
											TInt& aCount,
											RStringF aAlgorithm,
											RStringF aQop )
	{
	CSIPSecRequestData::TQop qop = SelectQopL( aHeader, aQop );
	if ( qop != CSIPSecRequestData::EUnknown )
		{
	    SelectAlgorithm( aHeader, iMechanism.Algorithm(), aAlgorithm );
		aHeader.SetParamL( SIPStrings::StringF( SipStrConsts::EAlgorithm ),
						   aAlgorithm );

	    CSIPSecChallenge* challenge( NULL );
	    if ( aAlgorithm == CSIPSecChallengeMD5::SupportedAlgorithm() )
	        {
	        challenge = CSIPSecChallengeMD5::NewLC( aType, aHeader, qop );
	        }
	    if ( aAlgorithm == CSIPSecChallengeAKA::SupportedAlgorithm() )
	        {
	        challenge = CSIPSecChallengeAKA::NewLC( aType, aHeader, qop );
	        }

	    if ( challenge )
	        {
	        AppendL( challenge );
	        CleanupStack::Pop( challenge );
	        ++aCount;
	        }
		}
    }
Example #2
0
void Sasl::respond(qpid::SaslServer::Status status, const std::string& chllnge)
{
    switch (status) {
      case qpid::SaslServer::OK:
        connection.setUserid(authenticator->getUserid());
        completed(true);
        //can't set authenticated & failed until we have actually sent the outcome
        state = SUCCESS_PENDING;
        securityLayer = authenticator->getSecurityLayer(65535);
        if (securityLayer.get()) {
            QPID_LOG_CAT(info, security, id << " Security layer installed");
            securityLayer->init(&connection);
            connection.setSaslSsf(securityLayer->getSsf());
        }
        QPID_LOG_CAT(info, security, id << " Authenticated as " << authenticator->getUserid());
        break;
      case qpid::SaslServer::FAIL:
        completed(false);
        state = FAILURE_PENDING;
        QPID_LOG_CAT(info, security, id << " Failed to authenticate");
        break;
      case qpid::SaslServer::CHALLENGE:
        challenge(&chllnge);
        QPID_LOG_CAT(info, security, id << " Challenge issued");
        break;
    }
    haveOutput = true;
    out.activateOutput();
}
Example #3
0
int             smb_session_login_spnego(smb_session *s, const char *domain,
        const char *user, const char *password)
{
    int           res;
    assert(s != NULL && domain != NULL && user != NULL && password != NULL);

    // Clear User ID that might exists from previous authentication attempt
    s->srv.uid = 0;

    if (init_asn1(s) != DSM_SUCCESS)
        return DSM_ERROR_GENERIC;

    if ((res = negotiate(s, domain)) != DSM_SUCCESS)
        goto error;
    if ((res = challenge(s)) != DSM_SUCCESS)
        goto error;

    res = auth(s, domain, user, password);

    clean_asn1(s);

    return res;

error:
    BDSM_dbg("login_spnego Interrupted\n");
    clean_asn1(s);
    return res;
}
/*!
 * \brief Check authentication using Digest scheme
 *
 * This function will check an incoming message against configured authentication
 * options. If \b any of the incoming Authorization headers result in successful
 * authentication, then authentication is considered successful.
 *
 * \see ast_sip_check_authentication
 */
static enum ast_sip_check_auth_result digest_check_auth(struct ast_sip_endpoint *endpoint,
		pjsip_rx_data *rdata, pjsip_tx_data *tdata)
{
	struct ast_sip_auth **auths;
	enum digest_verify_result *verify_res;
	enum ast_sip_check_auth_result res;
	int i;
	int failures = 0;
	size_t auth_size;

	RAII_VAR(struct ast_sip_endpoint *, artificial_endpoint,
		 ast_sip_get_artificial_endpoint(), ao2_cleanup);

	auth_size = AST_VECTOR_SIZE(&endpoint->inbound_auths);

	auths = ast_alloca(auth_size * sizeof(*auths));
	verify_res = ast_alloca(auth_size * sizeof(*verify_res));

	if (!auths) {
		return AST_SIP_AUTHENTICATION_ERROR;
	}

	if (endpoint == artificial_endpoint) {
		auths[0] = ast_sip_get_artificial_auth();
	} else if (ast_sip_retrieve_auths(&endpoint->inbound_auths, auths)) {
		res = AST_SIP_AUTHENTICATION_ERROR;
		goto cleanup;
	}

	for (i = 0; i < auth_size; ++i) {
		if (ast_strlen_zero(auths[i]->realm)) {
			ast_string_field_set(auths[i], realm, "asterisk");
		}
		verify_res[i] = verify(auths[i], rdata, tdata->pool);
		if (verify_res[i] == AUTH_SUCCESS) {
			res = AST_SIP_AUTHENTICATION_SUCCESS;
			goto cleanup;
		}
		if (verify_res[i] == AUTH_FAIL) {
			failures++;
		}
	}

	for (i = 0; i < auth_size; ++i) {
		challenge(auths[i]->realm, tdata, rdata, verify_res[i] == AUTH_STALE);
	}

	if (failures == auth_size) {
		res = AST_SIP_AUTHENTICATION_FAILED;
	} else {
		res = AST_SIP_AUTHENTICATION_CHALLENGE;
	}

cleanup:
	ast_sip_cleanup_auths(auths, auth_size);
	return res;
}
Example #5
0
std::string Logic::sendChallenge() {
    srand(time(0));
    std::string challenge(8,0);
        for(unsigned int i = 0; i < 8; ++i) {
            challenge[i] = rand() % 256;
        }
    std::cout<<challenge<<std::endl;//another errors
    std::string withHeader = "\001" +challenge;
    security.send(withHeader, 9);
    return challenge;
}
// -----------------------------------------------------------------------------
// RSIPSecChallengeResolver::Pop
// -----------------------------------------------------------------------------
//
CSIPSecChallenge* RSIPSecChallengeResolver::Pop()
    {
    CSIPSecChallenge* challenge( NULL );
    if ( Count() > 0 )
        {
        challenge = ( *this )[ 0 ];
        Remove( 0 );
        }

    return challenge;
    }
Example #7
0
static bool signature()
{
	return true;
	int chk = 1;
	FILE *fp; 
	fp = fopen ( eEnv::resolve("${sysconfdir}/stb/info/model").c_str(), "r");
	if (fp)
	{
		char line[256];
		int n;
		fgets(line, sizeof(line), fp);
 		if ((n = strlen(line)) && line[n - 1] == '\n')
		         line[n - 1] = '\0';
		fclose(fp);
		if (strstr(line,"dm7025"))
			chk = 0;
	}
	if (chk)
	{
	  	eTPM tpm;
		unsigned char rnd[CLEN];
		/* read random bytes */
		if (!read_random(rnd, CLEN))
			return 1;
		unsigned char level2_mod[128];
		unsigned char level3_mod[128];
		unsigned char buf[128];
		std::string challenge((char*)rnd, CLEN);
		std::string response = tpm.challenge(challenge);
		unsigned int len = response.size();
		unsigned char val[len];
		if ( len != 128 )
			return false;
		memcpy(val, response.c_str(), len);
		std::string cert = tpm.getCert(eTPM::TPMD_DT_LEVEL2_CERT);
		if ( cert.size() != 210 || !validate_cert(level2_mod, (const unsigned char*) cert.c_str(), tpm_root_mod))
			return false;
		cert = tpm.getCert(eTPM::TPMD_DT_LEVEL3_CERT);
		if ( cert.size() != 210 || !validate_cert(level3_mod, (const unsigned char*) cert.c_str(), level2_mod))
			return false;
		if (!decrypt_block(buf, val, 128, level3_mod))
			return false;
		if (memcmp(&buf[80], rnd, CLEN))
			return false;
		return true;
	}
	else
		return true;
}
    bool ManagerConnection::login(const std::string& eventMask) {
        if (!this->isConnected()) {
            LOG_ERROR_STR("Must connect before Login!!");
            return (false);
        } else if (this->isAuthenticated()) {
            LOG_ERROR_STR("Already Logged in!!");
            return (false);
        }

        if (this->getUsername().empty() || this->getPassword().empty()) {
            LOG_ERROR_STR("Must Provide UserName as Password!!");
            return (false);
        }

        LoginAction* la = NULL;
        ChallengeAction challengeAction("MD5");
        ChallengeResponse* carp = (ChallengeResponse*) this->syncSendAction(challengeAction);
        if (carp->isTypeSuccess()) {
            std::string challenge(carp->getChallenge());
            if (!challenge.empty()) {
                MD5 md5;
                md5.update(challenge.c_str(), challenge.length());
                md5.update(this->getPassword().c_str(), this->getPassword().length());
                md5.finalize();
                la = new LoginAction(this->getUsername(), "MD5", md5.hexdigest());
            }
        }
        delete (carp);

        if (!la) {
            la = new LoginAction(this->getUsername(), this->getPassword());
        }

        if (!eventMask.empty()) {
            la->setEvents(eventMask);
        }

        ManagerResponse *mr = this->syncSendAction(*la);
        bool rt(mr->isTypeSuccess());
        if (rt) {
            this->setState(AUTHENTICATED);
        }
        delete (la);
        delete (mr);

        return (rt);
    }
Example #9
0
PAM_EXTERN int
pam_sm_authenticate(pam_handle_t *pamh, int flags,
    int argc, const char *argv[])
{
	int ret;
	int faked = 0;
	const char *dir = NULL;
	const char *fake_suite = NULL;
	char *questions;
	const char *user;
	char *response = NULL;
	char fmt[512];

	(void)flags;
	(void)argc;
	(void)argv;

	pam_get_item(pamh, PAM_USER, (const void **)&user);

	openlog("pam_ocra", 0, LOG_AUTHPRIV);

	fake_suite = openpam_get_option(pamh, "fake_prompt");
	dir = openpam_get_option(pamh, "dir");
	if (PAM_SUCCESS != (ret = challenge(dir, user, &questions))) {
		if (PAM_NO_MODULE_DATA == ret && NULL != fake_suite) {
			if (PAM_SUCCESS !=
			    (ret = fake_challenge(fake_suite, &questions)))
				goto end;
			faked = 1;
		} else
			goto end;
	}
	snprintf(fmt, 512, "OCRA Challenge: %s\nOCRA  Response: ", questions);
	if (PAM_SUCCESS != (ret = get_response(pamh, fmt, &response)))
		goto end;
	if (1 == faked)
		ret = PAM_AUTH_ERR;
	else
		ret = verify(dir, user, questions, response);

	free(response);
end:
	closelog();
	return ret;
}
Example #10
0
std::string BeginUpdateKeyChangeResponse(
    uint8_t seq,
    uint32_t ksq,
    uint16_t user,
    const std::string& outstationChallenge
)
{
	Buffer buffer(DEFAULT_MAX_APDU_SIZE);
	APDUResponse apdu(buffer.GetWSlice());
	apdu.SetControl(AppControlField(true, true, false, false, seq));
	apdu.SetFunction(FunctionCode::AUTH_RESPONSE);
	apdu.SetIIN(IINBit::DEVICE_RESTART);

	HexSequence challenge(outstationChallenge);

	apdu.GetWriter().WriteFreeFormat(Group120Var12(ksq, user, challenge));

	return ToHex(apdu.ToRSlice());
}
Example #11
0
std::string BeginUpdateKeyChangeRequest(
    uint8_t seq,
    opendnp3::KeyChangeMethod method,
    const std::string& username,
    const std::string& masterChallenge
)
{
	Buffer buffer(DEFAULT_MAX_APDU_SIZE);
	APDURequest apdu(buffer.GetWSlice());
	apdu.SetControl(AppControlField(true, true, false, false, seq));
	apdu.SetFunction(FunctionCode::AUTH_REQUEST);

	RSlice name(reinterpret_cast<const uint8_t*>(username.c_str()), static_cast<uint32_t>(username.size()));
	HexSequence challenge(masterChallenge);

	apdu.GetWriter().WriteFreeFormat(Group120Var11(method, name, challenge));

	return ToHex(apdu.ToRSlice());
}
Example #12
0
File: tests.cpp Project: KnowNo/pal
static void test_request_challenge_response_sequence()
{
    std::auto_ptr<pal::ntlm_message> request(pal::create_ntlm_request());
    std::string request_str = pal::as_base64_string(request->as_bytes());
    std::string expected_request_str = "TlRMTVNTUAABAAAAAgIAAA==";
    ASSERT_TEST( expected_request_str == request_str );

    std::string challenge_str = "TlRMTVNTUAACAAAAAAAAADgAAAACAgAC6d1dZnbXIl4AAAAAAAAAAAAAAAA4AAAABQLODgAAAA8=";
    std::auto_ptr<pal::ntlm_message> challenge(pal::create_ntlm_challenge(pal::as_bytes_from_base64_string(challenge_str)));

    std::string username = "******";
    std::string password = "******";
    std::auto_ptr<pal::ntlm_message> response(pal::create_ntlm_response(username,password,*challenge));
    std::string response_str = pal::as_base64_string(response->as_bytes());
    std::string expected_response_str = "TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAADQANAHAAAAAAAAAAfQAAABAAEAB9AAAAAAIAABhBdYkMBBP/sMvC3ZmAZ3B8nlmh5E4NZGg5LnmDj4edn8Gk3G/m/6L8DA9GNbvV3EFkbWluaXN0cmF0b3IAAAAAAAAAAAAAAAAAAAAA";

    //std::cout << pal::as_hex_dump(response->as_bytes()) << std::endl;
    //std::cout << pal::as_hex_dump(pal::as_bytes_from_base64_string(expected_response_str)) << std::endl;
    ASSERT_TEST( expected_response_str == response_str );
}
Example #13
0
/*
* Create a PKCS #10 certificate request
*/
PKCS10_Request create_cert_req(const X509_Cert_Options& opts,
                               const Private_Key& key,
                               const std::string& hash_fn,
                               RandomNumberGenerator& rng)
   {
   AlgorithmIdentifier sig_algo;
   X509_DN subject_dn;
   AlternativeName subject_alt;

   opts.sanity_check();

   std::vector<byte> pub_key = X509::BER_encode(key);
   std::unique_ptr<PK_Signer> signer(choose_sig_format(key, hash_fn, sig_algo));
   load_info(opts, subject_dn, subject_alt);

   const size_t PKCS10_VERSION = 0;

   Extensions extensions;

   extensions.add(
      new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit));
   extensions.add(
      new Cert_Extension::Key_Usage(
         opts.is_CA ? Key_Constraints(KEY_CERT_SIGN | CRL_SIGN) :
                      find_constraints(key, opts.constraints)
         )
      );
   extensions.add(
      new Cert_Extension::Extended_Key_Usage(opts.ex_constraints));
   extensions.add(
      new Cert_Extension::Subject_Alternative_Name(subject_alt));

   DER_Encoder tbs_req;

   tbs_req.start_cons(SEQUENCE)
      .encode(PKCS10_VERSION)
      .encode(subject_dn)
      .raw_bytes(pub_key)
      .start_explicit(0);

   if(opts.challenge != "")
      {
      ASN1_String challenge(opts.challenge, DIRECTORY_STRING);

      tbs_req.encode(
         Attribute("PKCS9.ChallengePassword",
                   DER_Encoder().encode(challenge).get_contents_unlocked()
            )
         );
      }

   tbs_req.encode(
      Attribute("PKCS9.ExtensionRequest",
                DER_Encoder()
                   .start_cons(SEQUENCE)
                      .encode(extensions)
                   .end_cons()
               .get_contents_unlocked()
         )
      )
      .end_explicit()
      .end_cons();

   const std::vector<byte> req =
      X509_Object::make_signed(signer.get(), rng, sig_algo,
                               tbs_req.get_contents());

   return PKCS10_Request(req);
   }
Example #14
0
/*
 * Challenge a user to send credentials using Proxy-Authorize header field
 */
int proxy_challenge(struct sip_msg* _msg, char* _realm, char* _qop)
{
	return challenge(_msg, (gparam_p)_realm, (int)(long)_qop, 407,
			MESSAGE_407, PROXY_AUTH_CHALLENGE);
}
Example #15
0
/*
 * Challenge a user to send credentials using WWW-Authorize header field
 */
int www_challenge(struct sip_msg* _msg, char* _realm, char* _qop)
{
	return challenge(_msg, (gparam_p)_realm, (int)(long)_qop, 401,
			MESSAGE_401, WWW_AUTH_CHALLENGE);
}
WV_CencSingleSampleDecrypter::WV_CencSingleSampleDecrypter(std::string licenseURL, const uint8_t *pssh, size_t pssh_size)
  : AP4_CencSingleSampleDecrypter(0)
  , wv_adapter(0)
  , max_subsample_count_(0)
  , subsample_buffer_(0)
{
  uint8_t buf[1024];

  if (pssh_size > 256)
  {
    Log(SSD_HOST::LL_ERROR, "Init_data with length: %u seems not to be cenc init data!", pssh_size);
    return;
  }

  std::string strPath = host->GetDecrypterPath();
  if (strPath.empty())
  {
    Log(SSD_HOST::LL_ERROR, "Absolute path to widevine in settings expected");
    return;
  }
  strPath += WIDEVINECDMFILENAME;

  wv_adapter = new media::CdmAdapter("com.widevine.alpha", strPath.c_str(), media::CdmConfig());
  unsigned int buf_size = 32 + pssh_size;

  if (!wv_adapter->valid())
  {
    Log(SSD_HOST::LL_ERROR, "Unable to load widevine shared library (%s)", strPath.c_str());
    goto FAILURE;
  }

  // This will request a new session and initializes session_id and message members in cdm_adapter.
  // message will be used to create a license request in the step after CreateSession call.
  // Initialization data is the widevine cdm pssh code in google proto style found in mpd schemeIdUri
  static uint8_t proto[] = { 0x00, 0x00, 0x00, 0x63, 0x70, 0x73, 0x73, 0x68, 0x00, 0x00, 0x00, 0x00, 0xed, 0xef, 0x8b, 0xa9,
    0x79, 0xd6, 0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc, 0xd5, 0x1d, 0x21, 0xed, 0x00, 0x00, 0x00, 0x43 };

  memcpy(buf, proto, sizeof(proto));
  memcpy(&buf[32], pssh, pssh_size);

  wv_adapter->CreateSessionAndGenerateRequest(0, cdm::SessionType::kTemporary, cdm::InitDataType::kCenc, buf, buf_size);

  if (wv_adapter->SessionValid())
  {
    std::string license, challenge(b64_encode(wv_adapter->GetMessage(), wv_adapter->GetMessageSize(), true));
    challenge = "widevine2Challenge=" + challenge;
    challenge += "&includeHdcpTestKeyInLicense=true";

    // open the file
    void* file = host->CURLCreate(licenseURL.c_str());
    host->CURLAddOption(file, SSD_HOST::OPTION_PROTOCOL, "acceptencoding", "gzip");
    host->CURLAddOption(file, SSD_HOST::OPTION_PROTOCOL, "seekable", "0");
    host->CURLAddOption(file, SSD_HOST::OPTION_HEADER, "Content-Type", "application/x-www-form-urlencoded");

    size_t nbRead;
    std::string::size_type licStartPos, licEndPos;

    if (!host->CURLOpen(file, SSD_HOST::FILE_POST))
    {
      Log(SSD_HOST::LL_ERROR, "Failed to open CURL file");
      goto FAILURE;
    }

    if (size_t sz = host->WriteFile(file, challenge.c_str(), challenge.size()) != 200)
    {
      Log(SSD_HOST::LL_ERROR, "License server returned failure (%d)", static_cast<int>(sz));
      host->CloseFile(file);
      goto FAILURE;
    }

    // read the file
    while ((nbRead = host->ReadFile(file, buf, 1024)) > 0)
      license += std::string((const char*)buf,nbRead);

    host->CloseFile(file);

    if (nbRead != 0)
    {
      Log(SSD_HOST::LL_ERROR, "Could not read full license response");
      goto FAILURE;
    }

    licStartPos = license.find("\"license\":\"");
    if (licStartPos == std::string::npos)
    {
      Log(SSD_HOST::LL_ERROR, "License start position not found");
      goto FAILURE;
    }
    licStartPos += 11;
    licEndPos = license.find("\",", licStartPos);
    if (licEndPos == std::string::npos)
    {
      Log(SSD_HOST::LL_ERROR, "License end position not found");
      goto FAILURE;
    }

    buf_size = 1024;
    b64_decode(license.c_str() + licStartPos, licEndPos - licStartPos, buf, buf_size);
    wv_adapter->UpdateSession(buf, buf_size);

    if (!wv_adapter->KeyIdValid())
    {
      Log(SSD_HOST::LL_ERROR, "License update not successful");
      goto FAILURE;
    }
    // forbit auto delete for this object
    SetParentIsOwner(false);
    return;
  }
FAILURE:
  delete wv_adapter;
  wv_adapter = 0;
}
Example #17
0
cbsasl_error_t cram_md5_server_start(cbsasl_conn_t *conn)
{
    challenge(&(conn->c.server.sasl_data), &(conn->c.server.sasl_data_len));
    return SASL_CONTINUE;
}
Example #18
0
int
pq_verify(
    const size_t        packed_sig_len,
    const unsigned char *packed_sig,
    const size_t        public_key_blob_len,
    const unsigned char *public_key_blob,
    const size_t        msg_len,
    const unsigned char *msg)
{
  uint16_t      i;

  PQ_PARAM_SET  *P;
  size_t        scratch_len;
  unsigned char *scratch;
  int8_t        *sp;
  int8_t        *tp;
  int64_t       *h;
  int64_t       *sig;
  int64_t       *tmpx3;

  uint16_t      N;
  uint16_t      padN;
  int64_t       q;
  int8_t        p;
  uint16_t      error = 0;
  int           result;


  result = get_blob_params(&P, public_key_blob_len, public_key_blob);
  if(PQNTRU_ERROR == result)
  {
    return PQNTRU_ERROR;
  }

  N = P->N;
  padN = P->padded_N;
  p = P->p;
  q = P->q;

  scratch_len = 2 * N + 5 * POLYNOMIAL_BYTES(P);
  if(!(scratch = malloc(scratch_len)))
  {
    return PQNTRU_ERROR;
  }
  memset(scratch, 0, scratch_len);

  sig  = (int64_t*)scratch;
  h    = (int64_t*)(scratch + POLYNOMIAL_BYTES(P));
  tmpx3 = (int64_t*)(scratch + 2*POLYNOMIAL_BYTES(P));
  sp    =  (int8_t*)(scratch + 5*POLYNOMIAL_BYTES(P));
  tp    =  (int8_t*)(scratch + 5*POLYNOMIAL_BYTES(P) + N);

  result = unpack_public_key(P, h, public_key_blob_len, public_key_blob);
  if(PQNTRU_ERROR == result)
  {
    free(scratch);
    return PQNTRU_ERROR;
  }

  challenge(sp, tp,
            public_key_blob_len, public_key_blob,
            msg_len, msg);

  result = unpack_signature(P, sig, sp, packed_sig_len, packed_sig);
  if(PQNTRU_ERROR == result)
  {
    free(scratch);
    return PQNTRU_ERROR;
  }

  for(i=0; i<N; i++)
  {
    error |= (cmod(sig[i] - sp[i], p));
    error |= (sig[i] > P->norm_bound_s) || (-sig[i] > P->norm_bound_s);
  }
  pol_mul_coefficients(tmpx3, sig, h, N, padN, q, tmpx3);

  for(i=0; i<N; i++)
  {
    error |= (cmod(tmpx3[i], p) - tp[i]);
    error |= (tmpx3[i] > P->norm_bound_t) || (-tmpx3[i] > P->norm_bound_t) ;
  }



  free(scratch);

  if(0 == error)
  {
    return PQNTRU_OK;
  }
  return PQNTRU_ERROR;
}
void SessionParser::parse(const boost::uint8_t* p_data, boost::uint16_t p_length, boost::uint32_t p_srcAddr)
{
    switch(m_state) {
        case k_none:
            if (p_length > 13 && memcmp(p_data, "POST /jsproxy", 13) == 0) {
                std::cout << "[+] Initial request found." << std::endl;
                m_state = k_request;
            }
            break;
        case k_request:
            if (p_length > 17 && memcmp(p_data, "HTTP/1.1 200 OK\r\n", 17) == 0) {
                std::cout << "[+] Server challenge received." << std::endl;
                m_serverAddress = p_srcAddr;
                std::string packet;
                packet.assign(reinterpret_cast<const char*>(p_data), p_length);
                if (moveToPayload(packet) && packet.length() > 32) {
                    std::size_t index = 0;
                    for (std::size_t i = 0; i < 24 && index < packet.length(); i++) {
                        if (i < 8) {
                            codePointAt(packet, index);
                        } else {
                            m_rchallenge.push_back(codePointAt(packet, index));
                        }
                    }
                }
                m_state = k_challenge;
            }
            break;
        case k_challenge:
        {
            if (p_length < 13 || memcmp(p_data, "POST /jsproxy", 13) != 0) {
                break;
            }

            std::cout << "[+] Challenge response found." << std::endl;
            m_state = k_done;

            std::string packet;
            packet.assign(reinterpret_cast<const char*>(p_data), p_length);
            if (!moveToPayload(packet)) {
                std::cerr << "Failed to find the payload." << std::endl;
                break;
            }
            std::size_t index = 0;
            for (std::size_t i = 0; i < 26; i++) {
                codePointAt(packet, index);
            }
            m_lchallenge.assign(packet.data() + index, 16);
            index += 16;
            for (std::size_t i = 0; i < 8; i++) {
                codePointAt(packet, index);
            }
            for (std::size_t i = 0; i < 8 && index < packet.length(); i++) {
                m_response1.push_back(codePointAt(packet, index));
            }
            for (std::size_t i = 0; i < 8 && index < packet.length(); i++) {
                m_response2.push_back(codePointAt(packet, index));
            }
            for (std::size_t i = 0; i < 8 && index < packet.length(); i++) {
                m_response3.push_back(codePointAt(packet, index));
            }
            m_response.assign(m_response1);
            m_response.append(m_response2);
            m_response.append(m_response3);
            m_username.assign(packet.data() + index, packet.length() - index);
            std::cout << "Username: "******"Failed to recover key3!" << std::endl;
                return;
            }
            std::cout << "DES Key 3: ";
            printHexString(key3, true);

            // guess des key 2
            std::string key2;
            if (!getKey2(key2, m_response2, challengeHash)) {
                std::cerr << "Failed to recover key2!" << std::endl;
                return;
            }
            std::cout << "DES Key 2: ";
            printHexString(key2, true);

            // guess des key 1
            std::string key1;
            if (!getKey1(key1, m_response1, challengeHash)) {
                std::cerr << "Failed to recover key1!" << std::endl;
                return;
            }
            std::cout << "DES Key 1: ";
            printHexString(key1, true);

            // retrieve the pwdhash from our 3 keys
            std::string pwdHash(makePwdHash(key1));
            pwdHash.append(makePwdHash(key2));
            pwdHash.append(makePwdHash(key3));
            pwdHash.resize(16);
            std::cout << "Password SHA-1: ";
            printHexString(pwdHash);

            // create the pwd hash hash for master key creation
            std::string pwdHashHash(MD4::md4(pwdHash));
            std::cout << "SHA-1(Password SHA-1): ";
            printHexString(pwdHashHash);

            // create the master key
            std::string masterKey(pwdHashHash);
            masterKey.append(m_response);
            masterKey.append("This is the MPPE Master Key");

            unsigned char sharesult[20] = { 0 };
            sha1::calc(masterKey.data(), masterKey.size(), sharesult);
            masterKey.assign((char*)sharesult, 16);
            std::cout<< "Master Key: ";
            printHexString(masterKey);
        }
            break;
        case k_challenge_response:
        case k_decrypt:
        case k_done:
        default:
            break;
    }
}
Example #20
0
int
main( int argc, char *argv[] ) {

    /* make sure the provided username matches what the OS thinks */
    char * username = getenv( OS_AUTH_ENV_USER );
    if ( username == NULL ) {
        if ( argc > 0 ) {
            /* probably means someone has run from command-line */
            printf( "%s is run through an iRODS library call, and probably won't do anything useful for you.\n",
                    argv[0] );
            printf( "%s exiting.\n", argv[0] );
            return 1;
        }
        printf( "Username is null" );
        return 1;
    }
    char username2[NAME_LEN];
    int uid = osauthGetUsername( username2, NAME_LEN );
    if ( uid == -1 ) {
        return 1;
    }
    if ( strcmp( username, username2 ) ) {
        printf( "Username %s does not match OS user %s",
                username, username2 );
        return 1;
    }

    /* read the challenge from stdin */
    int challenge_len;
    if ( sizeof( challenge_len ) != read( 0, ( void* )&challenge_len, sizeof( challenge_len ) ) ) {
        printf( "Couldn't read challenge length from stdin: %s",
                strerror( errno ) );
        return 1;
    }
    if ( challenge_len != CHALLENGE_LEN ) {
        printf( "Challenge length must be %ju", ( uintmax_t )CHALLENGE_LEN );
        return 1;
    }
    std::vector<char> challenge( CHALLENGE_LEN );
    if ( CHALLENGE_LEN != read( 0, &challenge[0], CHALLENGE_LEN ) ) {
        printf( "Couldn't read challenge from stdin: %s",
                strerror( errno ) );
        return 1;
    }

    /* read the key from the key file */
    char * keybuf = NULL;
    int key_len;
    if ( osauthGetKey( &keybuf, &key_len ) ) {
        printf( "Error retrieving key. Exiting." );
        return 1;
    }

    char authenticator[16];  /* hard coded at 16 bytes .. size of an md5 hash */
    if ( osauthGenerateAuthenticator( username, uid, &challenge[0], keybuf, key_len, authenticator, 16 ) ) {
        printf( "Could not generate the authenticator" );
        return 1;
    }

    /* write out the authenticator to stdout */
    if ( write( 1, authenticator, 16 ) == -1 ) {
        int errsv = errno;
        printf( "Error %s writing the authenticator to stdout.",
                strerror( errsv ) );
        return 1;
    }

    return 0;
}
Example #21
0
  QByteArray CppDiffieHellman::VerifySharedSecret(const QByteArray &prover_pub,
      const QByteArray &remote_pub, const QByteArray &proof) const
  {
    // For modular arithmetic in our DH group
    CryptoPP::Integer modulus = _dh_params.GetGroupParameters().GetModulus();
    CryptoPP::Integer generator = _dh_params.GetGroupParameters().GetGenerator();
    CryptoPP::ModularArithmetic mod_arith(modulus);

    CppHash hash;

    QByteArray header = proof.mid(0, ZeroKnowledgeProofHeaderSize);
    QByteArray body = proof.mid(ZeroKnowledgeProofHeaderSize);

    int len_dh_secret = Utils::Serialization::ReadInt(header, 0);
    if(len_dh_secret < 1) return QByteArray();

    int len_challenge = Utils::Serialization::ReadInt(header, 4);
    if(len_challenge < 1) return QByteArray();

    int len_response = Utils::Serialization::ReadInt(header, 8);
    if(len_response < 1) return QByteArray();

    if(proof.size() < (ZeroKnowledgeProofHeaderSize+len_dh_secret+len_challenge+len_response)) {
      return QByteArray();
    }

    // Recover byte arrays of integers
    int offset = 0;
    QByteArray bytes_dh_secret = body.mid(offset, len_dh_secret);
    offset += len_dh_secret;
    QByteArray bytes_challenge = body.mid(offset, len_challenge);
    offset += len_challenge;
    QByteArray bytes_response = body.mid(offset, len_response);
   
    CppIntegerData dh_secret(bytes_dh_secret);
    CppIntegerData challenge(bytes_challenge);
    CppIntegerData response(bytes_response);

    // commit'_1 = (g^r) * (g^a)^c
    // commit'_1 = (g^r) * (public_key_a)^challenge
    CppIntegerData public_key_a(prover_pub);
    CryptoPP::Integer commit_1 = mod_arith.CascadeExponentiate(CppIntegerData(generator).GetCryptoInteger(), 
        response.GetCryptoInteger(), public_key_a.GetCryptoInteger(), challenge.GetCryptoInteger());

    // commit'_2 = (g^b)^r * (g^ab)^c
    // commit'_2 = (public_key_b)^response * (dh_secret)^challenge

    CppIntegerData public_key_b(remote_pub);
    CryptoPP::Integer commit_2 = mod_arith.CascadeExponentiate(public_key_b.GetCryptoInteger(), 
        response.GetCryptoInteger(), dh_secret.GetCryptoInteger(), challenge.GetCryptoInteger());

    // Group generator g
    QByteArray gen = CppIntegerData(generator).GetByteArray();

    // HASH(g, g^a, g^b
    QByteArray expected_challenge = hash.ComputeHash(gen + prover_pub + remote_pub + 
        bytes_dh_secret + CppIntegerData(commit_1).GetByteArray() + CppIntegerData(commit_2).GetByteArray());

    if(bytes_challenge == expected_challenge) {
      return bytes_dh_secret;
    } else {
      return QByteArray();
    }
  }
Example #22
0
QTSS_Error RTSPRequest::SendBasicChallenge(void)
{   
    QTSS_Error theErr = QTSS_NoErr;
    char *prefRealmPtr = NULL;
    
    do 
    {   
        char realmBuff[kRealmBuffSize] = "Basic realm=\"";
        StrPtrLen challenge(realmBuff);
        StrPtrLen whichRealm;
        
        // Get the module's realm
        StrPtrLen moduleRealm;
        theErr = this->GetValuePtr(qtssRTSPReqURLRealm, 0,  (void **) &moduleRealm.Ptr, &moduleRealm.Len);
        if ( (QTSS_NoErr == theErr) && (moduleRealm.Len > 0) )
        {
            whichRealm = moduleRealm;   
        }
        else
        {
            theErr = QTSS_NoErr;
            // Get the default realm from the config file or use the static default if config realm is not found
            QTSServerInterface* theServer = QTSServerInterface::GetServer();
            prefRealmPtr = theServer->GetPrefs()->GetAuthorizationRealm(); // allocates memory
            Assert(prefRealmPtr != NULL);
            if (prefRealmPtr != NULL)
            {   whichRealm.Set(prefRealmPtr, strlen(prefRealmPtr));
            }   
            else
            {
                whichRealm = sDefaultRealm;
            }
        }
        
        int realmLen = whichRealm.Len + challenge.Len + 2; // add 2 based on double quote char + end of string 0x00
        if (realmLen > kRealmBuffSize) // The realm is too big so use the default realm
        {   Assert(0);
            whichRealm = sDefaultRealm;
        }
        memcpy(&challenge.Ptr[challenge.Len],whichRealm.Ptr,whichRealm.Len);
        int newLen = challenge.Len + whichRealm.Len;
        
        challenge.Ptr[newLen] = '"'; // add the terminating "" this was accounted for with the size check above
        challenge.Ptr[newLen + 1] = 0;// add the 0 terminator this was accounted for with the size check above
        challenge.Len = newLen +1; // set the real size of the string excluding the 0.
        
        #if (0)
        {  // test code
            char test[256];
            
            memcpy(test,sDefaultRealm.Ptr,sDefaultRealm.Len);
            test[sDefaultRealm.Len] = 0;
            qtss_printf("the static realm =%s \n",test);
            
            OSCharArrayDeleter prefDeleter(QTSServerInterface::GetServer()->GetPrefs()->GetAuthorizationRealm());
            memcpy(test,prefDeleter.GetObject(),strlen(prefDeleter.GetObject()));
            test[strlen(prefDeleter.GetObject())] = 0;
            qtss_printf("the Pref realm =%s \n",test);

            memcpy(test,moduleRealm.Ptr,moduleRealm.Len);
            test[moduleRealm.Len] = 0;
            qtss_printf("the moduleRealm  =%s \n",test);
        
            memcpy(test,whichRealm.Ptr,whichRealm.Len);
            test[whichRealm.Len] = 0;
            qtss_printf("the challenge realm  =%s \n",test);
            
            memcpy(test,challenge.Ptr,challenge.Len);
            test[challenge.Len] = 0;
            qtss_printf("the challenge string  =%s len = %"_S32BITARG_"\n",test, challenge.Len);
        }
        #endif

        fStatus = qtssClientUnAuthorized;
        this->SetResponseKeepAlive(true);
        this->AppendHeader(qtssWWWAuthenticateHeader, &challenge);
        this->SendHeader();

    
    } while (false);
    
    if (prefRealmPtr != NULL)
    {   
        delete[] prefRealmPtr;  
    }
    
    return theErr;
}
Example #23
0
int main(int argc, char **argv)
{
    int sock, ret, r;
    struct sockaddr_in serv_addr;
    unsigned char send_data[SEND_DATA_SIZE];
    char recv_data[RECV_DATA_SIZE];
    struct drcom_conf *conf;
    struct drcom_info *info;
    struct drcom_host *host;
    struct user_info_pkt *user_info;

    /*FIXME: check malloc failure */
    conf = (struct drcom_conf *) malloc(sizeof(struct drcom_conf));
    info = (struct drcom_info *) malloc(sizeof(struct drcom_info));
    //session = (struct drcom_session_info *) malloc(sizeof(struct drcom_session_info));
    host = (struct drcom_host *) malloc(sizeof(struct drcom_host));
    //auth = (struct drcom_auth *) malloc(sizeof(struct drcom_auth));
    //keepalive = (struct drcom_host_msg *) malloc(sizeof(struct drcom_host_msg));
    //response = (struct drcom_host_msg *) malloc(sizeof(struct drcom_host_msg));
    user_info = (struct user_info_pkt *) malloc(sizeof(struct user_info_pkt));

    r = _readconf(conf, info, host, user_info);
    if (r)
    {
        fprintf(stderr, "[drcom]: read conf file failed.\n");
        return r;
    }

    sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0)
    {
        fprintf(stderr, "[drcom]: create sock failed.\n");
        exit(EXIT_FAILURE);
    }
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
    serv_addr.sin_port = htons(SERVER_PORT);

    // challenge data length 20
    challenge(sock, serv_addr, send_data, 20, recv_data, RECV_DATA_SIZE);

    //keep information for alive_data
    unsigned char keep_alive_msg[16];
    unsigned char keep_alive_authInfo[16];

    // login data length 330, salt length 4
    set_login_data(user_info, send_data, 330, (unsigned char *) (recv_data + 4),
            4, (unsigned char *) keep_alive_msg);
    memset(recv_data, 0x00, RECV_DATA_SIZE);
    login(sock, serv_addr, send_data, 330, recv_data, RECV_DATA_SIZE,
            keep_alive_authInfo, 16);

    // keep alive alive data length 40 or 38
    unsigned char tail[4];
    int tail_len = 4;
    memset(tail, 0x00, tail_len);

    int alive_data_len = 0;
    int alive_count = 0;
    int alive_fail_count = 0;
    do
    {
        if (alive_fail_count > ALIVE_TRY)
        {
            close(sock);
            fprintf(stderr,
                    "[drcom]: couldn't connect to network, check please.\n");
            exit(EXIT_FAILURE);
        }
        //alive_data_len = alive_count > 0 ? 40 : 42;
        alive_data_len = 38;
        set_alive_data(send_data, alive_data_len, keep_alive_msg,
                sizeof(keep_alive_msg), keep_alive_authInfo,
                sizeof(keep_alive_authInfo));
        ret = sendto(sock, send_data, alive_data_len, 0,
                (struct sockaddr *) &serv_addr, sizeof(serv_addr));
        if (ret != alive_data_len)
        {
            alive_fail_count++;
            fprintf(stderr, "[drcom]: send keep-alive data failed.\n");
            continue;
        }
        else
        {
            alive_fail_count = 0;
        }
        memset(recv_data, 0x00, RECV_DATA_SIZE);
        ret = recvfrom(sock, recv_data, RECV_DATA_SIZE, 0, NULL, NULL);
        if (ret < 0 || *recv_data != 0x07)
        {
            alive_fail_count++;
            fprintf(stderr,
                    "[drcom]: recieve keep-alive response data from server failed.\n");
            continue;
        }
        else
        {
            alive_fail_count = 0;
            //alive_count++;
        }

        //Misc Alive data
        set_misc1_data(send_data, 40, (unsigned char *) (recv_data + 4),
                alive_count);
        ret = sendto(sock, send_data, 40, 0, (struct sockaddr *) &serv_addr,
                sizeof(serv_addr));
        if (ret != 40)
        {
            alive_fail_count++;
            fprintf(stderr,
                    "[drcom]: send keep-alive MISC_TYPE1 data failed.\n");
            continue;
        }
        else
        {
            alive_fail_count = 0;
        }
        memset(recv_data, 0x00, RECV_DATA_SIZE);
        ret = recvfrom(sock, recv_data, RECV_DATA_SIZE, 0, NULL, NULL);
        if (ret < 0 || *recv_data != 0x07 && recv_data[5] != 0x02)
        {
            alive_fail_count++;
            fprintf(stderr,
                    "[drcom]: recieve keep-alive MISC_TYPE1 response data from server failed.\n");
            continue;
        }
        else
        {
            alive_fail_count = 0;
            alive_count++;
        }

        set_misc3_data(send_data, 40, (unsigned char *) (recv_data + 16),
                keep_alive_authInfo, alive_count);
        ret = sendto(sock, send_data, 40, 0, (struct sockaddr *) &serv_addr,
                sizeof(serv_addr));
        if (ret != 40)
        {
            alive_fail_count++;
            fprintf(stderr,
                    "[drcom]: send keep-alive MISC_TYPE3 data failed.\n");
            continue;
        }
        else
        {
            alive_fail_count = 0;
        }
        memset(recv_data, 0x00, RECV_DATA_SIZE);
        ret = recvfrom(sock, recv_data, RECV_DATA_SIZE, 0, NULL, NULL);
        if (ret < 0 || *recv_data != 0x07 && recv_data[5] != 0x04)
        {
            alive_fail_count++;
            fprintf(stderr,
                    "[drcom]: recieve keep-alive MISC_TYPE3 response data from server failed.\n");
            continue;
        }
        else
        {
            alive_fail_count = 0;
            alive_count++;
        }

        //if (alive_count > 1) memcpy(tail, recv_data+16, tail_len);
        sleep(20);
        fprintf(stdout, "[drcom]: keep alive.\n");
        //alive_count = (alive_count + 1) % 3;
    } while (1);

    close(sock);
    return 0;
}
Example #24
0
int main() {
    challenge();
    return 0;
}
Example #25
0
int
pq_sign(
    size_t              *packed_sig_len,
    unsigned char       *packed_sig,
    const size_t        private_key_len,
    const unsigned char *private_key_blob,
    const size_t        public_key_len,
    const unsigned char *public_key_blob,
    const size_t        msg_len,
    const unsigned char *msg)
{

  uint16_t i;
  int error = 0;

  uint16_t  N;
  uint16_t  padN;
  int64_t   q;
  int8_t    p;
  uint16_t  d1;
  uint16_t  d2;
  uint16_t  d3;
  int64_t   m;

  size_t        scratch_len;
  unsigned char *scratch;
  size_t        offset;

  uint16_t      *f;    /* Private key product form f indices */
  uint16_t      *g;    /* .. product form g indices */
  int64_t       *ginv; /* Private key; coefficients of g^{-1} */
  int64_t       *h;    /* Public key coefficients */
  int64_t       *s0;   /* scratch space for random lattice point */
  int64_t       *t0;

  int64_t       *a;    /* scratch space for 3 polynomials */
  int64_t       *tmpx2;/* scratch space for 2 polynomials (aliased by a) */

  int8_t        *sp;   /* Document hash */
  int8_t        *tp;


  PQ_PARAM_SET  *P;

  int rc = PQNTRU_OK;

  if(!private_key_blob || !public_key_blob || !packed_sig_len)
  {
    return PQNTRU_ERROR;
  }

  rc = get_blob_params(&P, private_key_len, private_key_blob);
  if(PQNTRU_ERROR == rc)
  {
    return PQNTRU_ERROR;
  }

  if(!packed_sig) /* Return signature size in packed_sig_len */
  {
    *packed_sig_len = SIGNATURE_BYTES(P);
    return PQNTRU_OK;
  }

  if(!msg || msg_len == 0)
  {
    return PQNTRU_ERROR;
  }

  N = P->N;
  padN = P->padded_N;
  q = P->q;
  p = P->p;
  d1 = P->d1;
  d2 = P->d2;
  d3 = P->d3;

  scratch_len = 2 * PRODUCT_FORM_BYTES(P) /* f and g */
              + 7 * POLYNOMIAL_BYTES(P)   /* h, ginv, and 5 scratch polys */
              + 2 * N;                    /* sp, tp */
  if(!(scratch = malloc(scratch_len)))
  {
    return PQNTRU_ERROR;
  }
  memset(scratch, 0, scratch_len);

  offset = 0;
  f    = (uint16_t*)(scratch);          offset += PRODUCT_FORM_BYTES(P);
  g    = (uint16_t*)(scratch + offset); offset += PRODUCT_FORM_BYTES(P);
  h    =  (int64_t*)(scratch + offset); offset += POLYNOMIAL_BYTES(P);
  ginv =  (int64_t*)(scratch + offset); offset += POLYNOMIAL_BYTES(P);
  s0   =  (int64_t*)(scratch + offset); offset += POLYNOMIAL_BYTES(P);
  t0   =  (int64_t*)(scratch + offset); offset += POLYNOMIAL_BYTES(P);
  /* a is treated as 3 polynomials, aliases tmpx2 */
  a    =  (int64_t*)(scratch + offset); offset += POLYNOMIAL_BYTES(P);
  tmpx2=  (int64_t*)(scratch + offset); offset += 2* POLYNOMIAL_BYTES(P);
  sp   =   (int8_t*)(scratch + offset); offset += N;
  tp   =   (int8_t*)(scratch + offset);


  /* Unpack the keys */
  rc = unpack_private_key(P, f, g, ginv, private_key_len, private_key_blob);
  if(PQNTRU_ERROR == rc)
  {
    shred(scratch, scratch_len);
    free(scratch);
    return PQNTRU_ERROR;
  }

  rc = unpack_public_key(P, h, public_key_len, public_key_blob);
  if(PQNTRU_ERROR == rc)
  {
    shred(scratch, scratch_len);
    free(scratch);
    return PQNTRU_ERROR;
  }


  /* Generate a document hash to sign */
  challenge(sp, tp,
            public_key_len, public_key_blob,
            msg_len, msg);

  int64_t *t = (int64_t *)malloc(N*sizeof(int64_t));
  int64_t *s = (int64_t *)malloc(N*sizeof(int64_t));

  do
  {
    error = 0;

    /* Choose random s0 satisfying s0 = sp (mod p) */
    pol_unidrnd_pZ(s0, N, q, p);
    for(i=0; i<N; i++)
    {
      s0[i] += sp[i];
    }

    /* Load h into a zero padded polynomial */
    memcpy(t0, h, N*sizeof(int64_t));

    /* t0 = h*s0 */
    pol_mul_coefficients(t0, t0, s0, N, padN, q, a);

    /* t0 = tp - (s0*h) */
    for(i=0; i<N; i++)
    {
      t0[i] *= -1;
      t0[i] += tp[i];
    }

    /* a = ginv * (tp - t0) (mod p) */
    pol_mul_coefficients(a, t0, ginv, N, padN, p, a);

    /* tmpx2 = a * F = (a * (f-1)/p) */
    pol_mul_product(tmpx2, a, d1, d2, d3, f, N, tmpx2);
    for(i=0; i<N; i++)
    {
      m = p * (a[i] + tmpx2[i]);
      error |= (m > P->B_s) || (-m > P->B_s);
      s[i] = m;
      /* s0 = s0 + p*(a + tmpx2) = s0 + a*f */
      s0[i] += m;

      error |= (cmod(s0[i], p) - sp[i]); /* Not necessary to check this */
      error |= (s0[i] > P->norm_bound_s) || (-s0[i] > P->norm_bound_s);
    }

    /* tmpx2 = a * G = (a * (g - 1)) */
    pol_mul_product(tmpx2, a, d1, d2, d3, g, N, tmpx2);
    for(i=0; i<N; i++)
    {
      m = (a[i] + tmpx2[i]);
      error |= (m > P->B_t) || (-m > P->B_t);
      t[i] = m;
      /* t0 = (a + tmpx2) - t0 + tp = a*g - tp + s0*h + tp = s0*h + a*g */
      t0[i] = m - t0[i] + tp[i];
      error |= (cmod(t0[i], p) - tp[i]); /* Not necessary to check this */
      error |= (t0[i] > P->norm_bound_t) || (-t0[i] > P->norm_bound_t) ;
    }


//    attempts ++;

  } while(0 != error);

  for (i=0; i<N; i++) {
	  if (s[i] > P->B_s || -s[i] > P->B_s)
		  printf("s\tholy shit\n");
	  if (t[i] > P->B_t || -t[i] > P->B_t)
		  printf("t\tholy shit\n");
  }

  for(i=0; i<N; i++)
  {
    s0[i] = (s0[i] - sp[i])/P->p;
    s0[i] += P->q / (2*P->p);
  }

  pack_signature(P, s0, *packed_sig_len, packed_sig);

  shred(scratch, scratch_len);
  free(scratch);

  return PQNTRU_OK;
}