001/* 002 * Copyright 2015-2024 the original author or authors 003 * 004 * This software is licensed under the Apache License, Version 2.0, 005 * the GNU Lesser General Public License version 2 or later ("LGPL") 006 * and the WTFPL. 007 * You may choose either license to govern your use of this software only 008 * upon the condition that you accept all of the terms of either 009 * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 010 */ 011package org.minidns.record; 012 013import org.minidns.record.NSEC3.HashAlgorithm; 014import org.minidns.record.Record.TYPE; 015 016import java.io.DataInputStream; 017import java.io.DataOutputStream; 018import java.io.IOException; 019import java.math.BigInteger; 020import java.util.Locale; 021 022/** 023 * NSEC3PARAM record payload. 024 */ 025public class NSEC3PARAM extends Data { 026 027 /** 028 * The cryptographic hash algorithm used. 029 * 030 */ 031 public final HashAlgorithm hashAlgorithm; 032 033 /** 034 * The cryptographic hash algorithm used. 035 * 036 */ 037 public final byte hashAlgorithmByte; 038 039 public final byte flags; 040 041 /** 042 * The number of iterations the hash algorithm is applied. 043 */ 044 public final int /* unsigned short */ iterations; 045 046 /** 047 * The salt appended to the next owner name before hashing. 048 */ 049 private final byte[] salt; 050 051 public static NSEC3PARAM parse(DataInputStream dis) throws IOException { 052 byte hashAlgorithm = dis.readByte(); 053 byte flags = dis.readByte(); 054 int iterations = dis.readUnsignedShort(); 055 int saltLength = dis.readUnsignedByte(); 056 byte[] salt = new byte[saltLength]; 057 if (dis.read(salt) != salt.length && salt.length != 0) throw new IOException(); 058 return new NSEC3PARAM(hashAlgorithm, flags, iterations, salt); 059 } 060 061 private NSEC3PARAM(HashAlgorithm hashAlgorithm, byte hashAlgorithmByte, byte flags, int iterations, byte[] salt) { 062 assert hashAlgorithmByte == (hashAlgorithm != null ? hashAlgorithm.value : hashAlgorithmByte); 063 this.hashAlgorithmByte = hashAlgorithmByte; 064 this.hashAlgorithm = hashAlgorithm != null ? hashAlgorithm : HashAlgorithm.forByte(hashAlgorithmByte); 065 066 this.flags = flags; 067 this.iterations = iterations; 068 this.salt = salt; 069 } 070 071 NSEC3PARAM(byte hashAlgorithm, byte flags, int iterations, byte[] salt) { 072 this(null, hashAlgorithm, flags, iterations, salt); 073 } 074 075 @Override 076 public TYPE getType() { 077 return TYPE.NSEC3PARAM; 078 } 079 080 @Override 081 public void serialize(DataOutputStream dos) throws IOException { 082 dos.writeByte(hashAlgorithmByte); 083 dos.writeByte(flags); 084 dos.writeShort(iterations); 085 dos.writeByte(salt.length); 086 dos.write(salt); 087 } 088 089 @Override 090 public String toString() { 091 StringBuilder sb = new StringBuilder() 092 .append(hashAlgorithm).append(' ') 093 .append(flags).append(' ') 094 .append(iterations).append(' ') 095 .append(salt.length == 0 ? "-" : new BigInteger(1, salt).toString(16).toUpperCase(Locale.ROOT)); 096 return sb.toString(); 097 } 098 099 public int getSaltLength() { 100 return salt.length; 101 } 102}