Google Tink: How to get raw key string from a KeysetHandle? - tink

I am new to Tink and would like to extract the raw key data(in String form) from KeysetHandle which I generated like this:
keysetHandle = KeysetHandle.generateNew(
AeadKeyTemplates.AES128_GCM);
Or maybe some other API to get it.
How can I achieve this?

You can write the Keyset to disk with either KeysetHandle.write(), which requires encryption, other CleartextKeysetHandle.write(). Both require a BinaryKeysetWriter or JsonKeysetWriter.

Example will help. Here is how you would use CleartextKeysetHandle.write() to observe the key profile:
Try this for display:
// display key [Caveat: ONLY for observation]
public void display_key_profile_for_test_observation_only(KeysetHandle keysetHandle) throws IOException, GeneralSecurityException
{
System.out.println("\nDisplay key:");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CleartextKeysetHandle.write(keysetHandle, JsonKeysetWriter.withOutputStream(outputStream));
System.out.println("\n"+ new String(outputStream.toByteArray()));
}
As this belongs to a class, you may have to do some slight code modification. You see the keyword this denoting that the code snippets come from a class. Here is the test usage:
public void trial_usage_key_generation() throws IOException, GeneralSecurityException {
for (CIPHER_SYMMETRIC_ALGOS algo_type : CIPHER_SYMMETRIC_ALGOS.values()) {
System.out.println("Generating key for : " + algo_type);
KeysetHandle keysetHandle = this.generate_key_for_test_observation_only(algo_type);
this.display_key_profile_for_test_observation_only(keysetHandle);
}
}

You can use reflection to get the keyset as code below, or JsonKeysetWriter to get base64ed key bytestring (still needs to be unserialized to corresponding key object to get the raw key bytes).
KeysetHandle keysetHandle = KeysetHandle.generateNew(
AeadKeyTemplates.CHACHA20_POLY1305);
Method method = keysetHandle.getClass().getDeclaredMethod("getKeyset");
method.setAccessible(true);
Keyset keyset = (Keyset) method.invoke(keysetHandle);
ChaCha20Poly1305Key key = ChaCha20Poly1305Key.parseFrom(keyset.getKey(0).getKeyData().getValue());
byte[] keyBytes = key.getKeyValue().toByteArray();

Related

Map one field value to other field using Gson on condition like if first one is null or having value zero

I am trying to map one field value to other if that is null or zero. I am using Gson library to parse Json. Is there any way to map values on condition base. I tried using JsonAdapter where I can put condition for that field but unable to find out solution how to get other field value there to put in that.
Write your own deserializer implementing JsonDeserializer<Element> something like below according json response-
class CustomDeserializer implements JsonDeserializer<Element> {
#Override
public Element deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
JsonObject jobject = json.getAsJsonObject();
JsonObject object = jobject.get("key").getAsJsonObject();
if(object == null){
}
return null;
}
}
Usage -
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Element.class, new CustomDeserializer());
Gson gson = gsonBuilder.create();

How do I use SimpleFileVisitor in Java to find a file name whose encoding may vary?

I'm using SimpleFileVisitor to search for a file. It works fine on Windows and Linux. However when I try using it on Unix like operating systems It doesn't work as expected. I would get errors like this:
java.nio.file.NoSuchFileException:
/File/Location/MyFolder/\u0082\u0096\u0096âĜu0099\u0081\u0097K
\u0097\u0099\u0096\u0097\u0085\u0099Ĝu0089\u0085
It looks like the obtained name is in different character encoding and maybe that is what causing the issue. It looks like in between the obtaining the name and trying to obtain the access to the file, the encoding is getting missed up. This result in calling preVisitDirectory once then visitFileFailed for every file it tries to visit. I'm not sure why the walkFileTree method is doing that. Any idea?
My using for SimpleFileVisitor code looks like this:
Files.walkFileTree(serverLocation, finder);
My SimpleFileVisitor class:
public class Finder extends SimpleFileVisitor<Path> {
private final PathMatcher matcher;
private final List<Path> matchedPaths = new ArrayList<Path>();
private String usedPattern = null;
Finder(String pattern) {
this.usedPattern = pattern;
matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
}
void match(Path file) { //Compare pattern against file or dir
Path name = file.getFileName();
if (name != null && matcher.matches(name))
matchedPaths.add(file);
}
// Check each file.
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
match(file);
return CONTINUE;
}
// Check each directory.
#Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
match(dir);
return CONTINUE;
}
#Override
public FileVisitResult visitFileFailed(Path file, IOException e) {
System.out.println("Issue: " + e );
return CONTINUE;
}
Try using "Charset.defaultCharset()" when you create those "file" and "dir" strings you pass around. Otherwise, you could very likely mangle the names in the process of creating those strings to pass them to your visit methods.
You might also check your default encoding on the JVM your are running, if it is out of sync with the file system you are reading, your results will be, err, unpredictable.

JSF2 custom component (UIInput) 'value' attribute

Hi I'm trying to create a custom component that extends UIInput. In that component I generate one html input, one html submit button and one line of text. The codes are as below:
#Override
public void decode(FacesContext context) {
Map requestMap = context.getExternalContext().getRequestParameterMap();
String clientId = getClientId(context);
char sep = UINamingContainer.getSeparatorChar(context);
String symbol = ((String) requestMap.get(clientId + sep + "inputfield"));
setSubmittedValue(symbol);
}
#Override
public void encodeEnd(FacesContext context) throws IOException {
String clientId = getClientId(context);
char sep = UINamingContainer.getSeparatorChar(context);
//-----------------------this generates an html input-------------------------
encodeInputField(context, clientId + sep + "inputfield");
//Now if I uncomment the next line it generates another html, whose value always stays the same as the first one
//encodeInputField(context, clientId + sep + "inputfield2");
encodeSubmitButton(context, clientId + sep + "submit");
encodeOutputField(context);
}
private void encodeInputField(FacesContext context, String clientId) throws IOException {
// Render a standard HTML input field
ResponseWriter writer = context.getResponseWriter();
writer.startElement("input", this);
writer.writeAttribute("type", "text", null);
writer.writeAttribute("name", clientId, "clientId");
Object value = getValue();
if (value != null) {
writer.writeAttribute("value", value.toString(), "value");
}
writer.writeAttribute("size", "6", null);
writer.endElement("input");
}
private void encodeSubmitButton(FacesContext context, String clientId) throws IOException {
// render a submit button
ResponseWriter writer = context.getResponseWriter();
writer.startElement("input", this);
writer.writeAttribute("type", "Submit", null);
writer.writeAttribute("name", clientId, "clientId");
writer.writeAttribute("value", "Click Me!", null);
writer.endElement("input");
}
private void encodeOutputField(FacesContext context) throws IOException {
ResponseWriter writer = context.getResponseWriter();
//----------------weird value that comes out of nowhere-----------------------
String hellomsg = (String) getAttributes().get("value");
writer.startElement("p", this);
writer.writeText("You entered: " + hellomsg, null);
writer.endElement("p");
}
Now everything works fine but I don't understand where the value attribute in String hellomsg = (String) getAttributes().get("value"); comes. I tried to debug this program and the getAttributes() hashmap also contains weird entries and I couldn't find any entry whose key is "value".
Finally if I generate two html input then the second input's value always stays the same as the first one.
I also noticed that I can include a value in the tag, e.g. <mycc:cinput value="yes"> and when the page loads, the value of the html input generated is set to yes.
My doubt is: is every UIInput has a default value attribute? If so, is that attribute value always linked to whatever html input's value attribute? If so, is it always linked to the value attribute of the first html input generated?
Thanks in advance for reading such a long question. If possible can you guys let me know where I can find answers to issues like this? Im getting a headache browsing random google search results#_#
Thanks a lot!
Now everything works fine but I don't understand where the value attribute in String hellomsg = (String) getAttributes().get("value"); comes. I tried to debug this program and the getAttributes() hashmap also contains weird entries and I couldn't find any entry whose key is "value".
Read the javadoc of UIComponent#getAttributes(). To the point, it's really an abstract map. The get("value") doesn't really return an entry from the map, but it basically obtains the value property of the component itself by invoking its getValue() method, if any available (and it is, in case of UIInput). But if you're already sitting in the component itself, you don't need to invoke getAttributes().get("value"), you can just invoke the getValue() method directly.
Note thus that if you intend to put a custom attribute in the attribute map, then you should be using a different name, or, better, to make use of StateHelper.
See also:
JSF custom component: support for arguments of custom types, the attribute setter is never invoked
How to save state when extending UIComponentBase

Posting multipart form data to seam+RESTeasy fails marshalling to InputStream

I'm trying to post image data to a seam+RESTeasy endpoint and I'm getting a very cryptic error during JBoss startup. The HTTP request I'm sending has a content-type of multipart/form-data which has a single image/jpeg part with name "attachment". My service method looks like this:
#POST
#Path("uploadSymptomsImage/{appointmentGUID}")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces("application/json")
public String uploadSymptomsImage( #FormParam("attachment") InputStream fileInputStream,
#PathParam("appointmentGUID") String strAppointmentGUID )
{ ...
The error that I get is during startup:
Caused by: java.lang.RuntimeException: Unable to find a constructor that takes a String param or a valueOf() or fromString() method for javax.ws.rs.FormParam("attachment") on public java.lang.String com....AppointmentRestService.uploadSymptomsImage(java.io.InputStream,java.lang.String) for basetype: java.io.InputStream
at org.jboss.resteasy.core.StringParameterInjector.initialize(StringParameterInjector.java:206) [:]
at org.jboss.resteasy.core.StringParameterInjector.<init>(StringParameterInjector.java:57) [:]
at org.jboss.resteasy.core.FormParamInjector.<init>(FormParamInjector.java:22) [:]
My understanding was that media types could be automatically marshalled to InputStream. I've also tried java.io.File, java.io.Reader - both with same error. When I replace with byte[] or String I get a zero length array, or null as the parameter value.
How would you go about debugging this? Also, is it possible to access the raw request or pre-marshalled values?
Any suggestions here would be greatly appreciated.
You should retrieve the contents using MultipartFormDataInput. See the following example:
#POST
#Path("uploadSymptomsImage/{appointmentGUID}")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces("application/json")
public String uploadSymptomsImage(#PathParam("appointmentGUID") String strAppointmentGUID,
MultipartFormDataInput formData) {
Map<String, List<InputPart>> formDataMap = formData.getFormDataMap();
List<InputPart> attachments = formDataMap.get("attachment");
for(InputPart attachment : attachments) {
String fileName = extractFilename(attachment);
if(fileName.isEmpty()) continue;
InputStream in = attachment.getBody(new GenericType<InputStream>() {});
// Interact with stream
}
// Respond
}
The extractFilename method is a helper method I wrote:
private static String extractFilename(final InputPart attachment) {
Preconditions.checkNotNull(attachment);
MultivaluedMap<String, String> headers = attachment.getHeaders();
String contentDispositionHeader = headers.getFirst("Content-Disposition");
Preconditions.checkNotNull(contentDispositionHeader);
for(String headerPart : contentDispositionHeader.split(";(\\s)+")) {
String[] split = headerPart.split("=");
if(split.length == 2 && split[0].equalsIgnoreCase("filename")) {
return split[1].replace("\"", "");
}
}
return null;
}

Accessing encoded stream in OpenRasta

I have a need to access the encoded stream in OpenRasta before it gets sent to the client. I have tried using a PipelineContributor and registering it before KnownStages.IEnd, tried after KnownStages.IOperationExecution and after KnownStages.AfterResponseConding but in all instances the context.Response.Entity stream is null or empty.
Anyone know how I can do this?
Also I want to find out the requested codec fairly early on yet when I register after KnowStages.ICodecRequestSelection it returns null. I just get the feeling I am missing something about these pipeline contributors.
Without writing your own Codec (which, by the way, is really easy), I'm unaware of a way to get the actual stream of bytes sent to the browser. The way I'm doing this is serializing the ICommunicationContext.Response.Entity before the IResponseCoding known stage. Pseudo code:
class ResponseLogger : IPipelineContributor
{
public void Initialize(IPipeline pipelineRunner)
{
pipelineRunner
.Notify(LogResponse)
.Before<KnownStages.IResponseCoding>();
}
PipelineContinuation LogResponse(ICommunicationContext context)
{
string content = Serialize(context.Response.Entity);
}
string Serialize(IHttpEntity entity)
{
if ((entity == null) || (entity.Instance == null))
return String.Empty;
try
{
using (var writer = new StringWriter())
{
using (var xmlWriter = XmlWriter.Create(writer))
{
Type entityType = entity.Instance.GetType();
XmlSerializer serializer = new XmlSerializer(entityType);
serializer.Serialize(xmlWriter, entity.Instance);
}
return writer.ToString();
}
}
catch (Exception exception)
{
return exception.ToString();
}
}
}
This ResponseLogger is registered the usual way:
ResourceSpace.Uses.PipelineContributor<ResponseLogger>();
As mentioned, this doesn't necessarily give you the exact stream of bytes sent to the browser, but it is close enough for my needs, since the stream of bytes sent to the browser is basically just the same serialized entity.
By writing your own codec, you can with no more than 100 lines of code tap into the IMediaTypeWriter.WriteTo() method, which I would guess is the last line of defense before your bytes are transferred into the cloud. Within it, you basically just do something simple like this:
public void WriteTo(object entity, IHttpEntity response, string[] parameters)
{
using (var writer = XmlWriter.Create(response.Stream))
{
XmlSerializer serializer = new XmlSerializer(entity.GetType());
serializer.Serialize(writer, entity);
}
}
If you instead of writing directly to to the IHttpEntity.Stream write to a StringWriter and do ToString() on it, you'll have the serialized entity which you can log and do whatever you want with before writing it to the output stream.
While all of the above example code is based on XML serialization and deserialization, the same principle should apply no matter what format your application is using.

Resources