in src/generic/nca_d.c [173:259]
int Web_DecryptD(ClientData clientData,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
Tcl_Obj *key = NULL;
//unsigned char *keyBytes = NULL;
int keyLen = -1;
char *str = NULL;
int strLen = -1;
Tcl_Obj *out = NULL;
Tcl_Obj *tmp = NULL;
/* --------------------------------------------------------------------------
* sanity
* ----------------------------------------------------------------------- */
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "msg");
return TCL_ERROR;
}
WebAssertData(interp, clientData, "web::decryptd", TCL_ERROR);
key = (Tcl_Obj *) clientData;
Tcl_GetByteArrayFromObj(key, &keyLen);
if (keyLen < 1) {
LOG_MSG(interp, SET_RESULT,
__FILE__, __LINE__,
"web::decryptd", WEBLOG_ERROR, "too short key", NULL);
return TCL_ERROR;
}
/* --------------------------------------------------------------------------
* check crypt tag
* ----------------------------------------------------------------------- */
str = Tcl_GetStringFromObj(objv[1], &strLen);
if ((strLen >= 2) && (str[0] == 'X') && (str[1] == 'D')) {
/* XD --> "" */
if (strLen == 2) {
Tcl_SetResult(interp, "", NULL);
return TCL_OK;
}
/* ------------------------------------------------------------------------
* decrypt
* --------------------------------------------------------------------- */
tmp = decryptNcaD(key, objv[1]);
if (tmp == NULL) {
LOG_MSG(interp, SET_RESULT,
__FILE__, __LINE__,
"web::decryptd", WEBLOG_DEBUG, "internal error", NULL);
return TCL_ERROR;
}
/* ------------------------------------------------------------------------
* veryfy checksum
* --------------------------------------------------------------------- */
out = crcCheck(tmp); /* rturns NULL in case of error */
if (out == NULL) {
/* just set interp result, but don't actually log: will be logged by
caller */
LOG_MSG(interp, SET_RESULT,
__FILE__, __LINE__,
"web::decryptd", WEBLOG_ERROR, "checksum mismatch", NULL);
WebDecrRefCountIfNotNull(tmp);
return TCL_ERROR;
}
Tcl_DecrRefCount(tmp);
Tcl_SetObjResult(interp, out);
Tcl_DecrRefCount(out);
return TCL_OK;
}
LOG_MSG(interp, WRITE_LOG,
__FILE__, __LINE__,
"web::decryptd", WEBLOG_DEBUG, "crypt type not recognized", NULL);
return TCL_CONTINUE;
}